2012-02-17 2 views
4

클래스/인터페이스 계층 구조가 있습니다. 인터페이스 측면에서 나는 단지 선택은 너무 이상적으로 기능에 의해 그룹이 내가 분명히유창한 인터페이스에서 유형 유추 사용

QueryBase  (implements IQuery) 
    SelectQuery (implements ISelect) 
    UpdateQuery (implements IUpdate) 
    etc 

이, 예를 들어, 업데이트 및 선택 클래스 모두가 WHERE 절하지만 공유 클래스 측면에서

IQuery 
    ISelect  (inherits IQuery) 
    IUpdate  (inherits IQuery) 
    etc 

이 업데이트 쿼리가 생성되면 유창한 인터페이스는 GROUP BY 기능에 대한 액세스 권한을 부여하지 않지만 SelectQuery가 생성되면 수행 할 수 있습니다. 유창 인터페이스 측면에서

예를 들면

var/Dim select = New SelectQuery()  <- returns ISelect explicit 
          .AddColumn(....) <- returns ISelect explicit 
          .AddWhere(....) <- returns ISelect inferred 
          .AddGroupBy(....) <- returns ISelect explicit 

    var/Dim update = New UpdateQuery()  <- returns IUpdate explicit 
          .AddSet(....)  <- returns IUpdate explicit 
          .AddWhere(....) <- returns IUpdate inferred 

나는 AddWhere 기능을 구현하는 방법을 확실입니다.

는 이전에 나는

Function AddWhere(ByVal condition As ICriterion) As IQuery 

IQuery AddWhere(ICriterion condition) 

로 IQUERY 인터페이스의 AddWhere 기능을 선언했지만 그것이 IQUERY을 반환했기 때문에, 나는 타입 추론의 장점을 잃고 그래서 즉시 유창 인터페이스는 주조 한대로 IQuery에 생성 된 Select 쿼리 인 경우 더 이상 예를 들어 AddGroupBy 메서드에 액세스 할 수 없습니다.

은 그래서 WHERE 절을 업데이트 할 날을 허용 QueryBase에, 제네릭 친구 (내부) 방법, SetWhere와
<Extension> 
Public Function AddWhere(Of T As IQuery)(Byval this as T, Byval condition as Condition) as T 
    this.SetWhere(condition) 
    Return Me 
End Function 

public T AddWhere<T>(T @this, Condition condition) where T : IQuery 
{ 
    @this.SetWhere(condition); 
    return this; 
} 

와 함께 확장 메서드로 구현하기 위해 노력했다. 그러나 제네릭은 IQuery에 제약되어 있으므로 SetWhere를 찾지 못합니다. 그러나 QueryBase로 제한하면 컴파일러에서 ISelect가 AddWhere 메서드를 찾을 수 없다는 메시지를 던집니다.

내가 달성하려고 시도하고있는 것에 대해 상속 체인 또는 인터페이스 구현이 제대로되지 않았다고 생각합니다.

(I가 분명 희망!)

누군가가 제안 할 수 있다면 나는 감사 할 것 중 하나 나는 확장 메서드 구현, 또는 어떻게 더 나은 내 클래스/인터페이스를 구성해야 측면에서 잘못 가고 어디에 계층.

+1

나는 당신이 무엇을 단순화 된 형태에 대해 설명하기 때문에 http://stackoverflow.com/questions/1723648/how-to-inherit-method-but-with-different-return-type 유용 읽는 것 같아요 노력하고있어. 대체로 기본 클래스 인 Generic을 포함하는 몇 가지 해결 방법이 있지만 가능하지 않다고합니다. 난 당신이 코드의 구조 조정에 만족한다면이 마지막 부분 (dtb의 대답) 아마 당신이 원하는 것을 할 것이라고 생각합니다. – Chris

+0

Chris 나는 이걸 좀 연주했다. 그 q 구체적인 클래스에 이야기하고 내 시나리오가 인터페이스 계층 구조로 복잡합니다 경우 궁금 해서요.나는 QueryBase를 QueryBase (IQuery와 같은 T)로 범용화하려고 시도했지만, 그렇다면 AFAICS는 "SelectQuery factory"가 ISelect가 아닌 Selectelect 또는 QueryBase 중 하나를 반환해야한다는 것을 의미합니다. 마찬가지로 유창한 방법은 콘크리트를 반환해야합니다. 나는 ISP/mocking의 용이함 때문에 순수 인터페이스를 반환하고있었습니다. 내가 놓친 게 있니? –

+0

나는 잘 모르겠다. 나는 그 질문이 약간 다르다는 것을 알고 있으며 그것이 작동한다면 약간의 적응이 필요할 것이다. 그러나 나는 전에 이것을하지 않았고 그것으로 스스로 놀 수있는 시간이 없다. 그 질문들이 당신이 일을 완벽하게 해결하는 데 도움이되지 않을 수도 있습니다, 나는 단지 바랬습니다. ;-) – Chris

답변

1
Public Interface IQuery 
    Function AddWhere() As IQuery 
End Interface 

Public Interface IUpdate : Inherits IQuery 
    Overloads Function AddWhere() As IUpdate 
End Interface 

Public Interface ISelect : Inherits IQuery 
    Overloads Function AddWhere() As ISelect 
    Function AddGroupBy() As ISelect 
End Interface 

Public Class QueryBase : Implements IQuery 
    Public Function AddWhere() As IQuery Implements IQuery.AddWhere 
     ''... 
     Return Me 
    End Function 
End Class 

Public Class UpdateQuery : Inherits QueryBase : Implements IUpdate 
    Public Shadows Function AddWhere() As IUpdate Implements IUpdate.AddWhere 
     MyBase.AddWhere() 
     Return Me 
    End Function 
End Class 

Public Class SelectQuery : Inherits QueryBase : Implements ISelect 
    Public Shadows Function AddWhere() As ISelect Implements ISelect.AddWhere 
     MyBase.AddWhere() 
     Return Me 
    End Function 
    Public Function AddGroupBy() As ISelect Implements ISelect.AddGroupBy 
     ''... 
     Return Me 
    End Function 
End Class 
+0

우수. Thx Ian –

+0

당신은 환영합니다 - 나는 대답 할 때까지 얼마나 오래된 질문인지 알지 못했습니다. 다행이라면 여전히 유용합니다. –

0

아마 당신이 당신의 계층 구조에서 다른 인터페이스를 사용할 수 있습니다, 뭔가 같은 :

interface IQuery 

interface IConditional : IQuery 

interface ISelect : IConditional 

interface IUpdate : IConditional 

IConditional 인터페이스는 직접 인터페이스 정의 또는 IConditional 종류에 제약이 확장 방법으로 하나의 AddWhere 방법을 가질 수있다 .

+0

AddWhere는 어떻게 되나요? 그 상황에서 여전히 Iquery 나 IConditional을 반환해야합니까? – Chris

+0

질문을 다시 읽으면, 'AddWhere'가 선택을위한'AddGroupBy' 전에 오게 된 이유가 있습니까? 또한 궁극적으로 당신은 무엇을 돌려주고 싶습니까? 내게는 var이'IQuery' 타입 일 것입니다. 그런 다음 어떤 종류의 실행 메소드가 올바른 것입니까? –

+0

나는 그 무엇보다 대답이 의심 스럽습니다. 왜 그것이 오지 말아야하는지에 대한 이유가 무엇입니까? 유창한 물건의 요점은 그 방법이 그들이 실행 중이던 동일한 객체를 반환한다고 믿습니다. ISelect에서 메소드를 실행하면 Ielect를 반환하지 말고 ISelect를 다시 얻어야합니다. AddWhere를 마지막으로 제약한다면 방법이 있습니다. 그러나 예를 들어 다른 메소드 세트에 액세스 할 수 있기 때문에 유창하지는 않을 것입니다. 나는 또한 나의 포스터가 자신의 견해가 아닐 수도 있다는 점을 알아야한다. :) – Chris

관련 문제