2012-03-14 5 views
2

이 비주얼 스튜디오 2010에서얻기 경고 '를 입력 매개 변수 X 숨기 인터페이스 X'

나는 일반적인 방법과 작업, 기본적으로 내 인텔리 손실이 프로젝트에 대한 작업을 계속에서 저를 중단하고있어 발생합니다. 그래서 내가이 일을 기대 정확히 어떻게 작품을 삭제

public abstract class DataRepository<T> 
{ 
    public virtual IEnumerable<T> RetrieveAll<U>(U parameter1) 
    { 
     throw new NotImplementedException(); 
    } 

    public virtual bool Delete<U>(U parameter1) 
    { 
     throw new NotImplementedException(); 
    } 
} 

:에서이 상속

public class SearchRepository : DataRepository<IAudit> 
{ 
    public override IEnumerable<IAudit> RetrieveAll<IAuditSearch>(IAuditSearch searchParameters) 
    { 
     // CODE GOES HERE 
    } 

    public override bool Delete<TIAudit>(IAudit audit) 
    { 
     // CODE GOES HERE 
    } 
} 

:

나는 기본적으로 다음과 같은 클래스가 있습니다. 나는 인텔리 센스가 있고 올바르게 컴파일됩니다. RetrieveAll은 IAuditSearch를 사용하여 올바르게 작동하지 않습니다. TIAuditSearch로 변경하면 "나는 재정의 할 수있는 적절한 방법이 없다"고합니다.

내가 잘못하고있는 것이 확실하지 않지만 확실히 나와 행복하지 않습니다.

UPDATED : 맨 위의 Delete 메소드에 대해 가상을 재정의하도록 변경했습니다. 그건 실수 였어.

+0

'추상'유형의 구현이없는'virtuals'을 사용하는 것이 맞습니까? 나는 당신이 대신에 추상적 인 키워드를 사용해야한다고 생각한다. – Tigran

+0

그 이유는 내가 코드의 일부만을 보여준 때문이다. 초록에는 8-10 가지 방법이 있습니다. 각 저장소는 그 중 일부만 대체합니다. – Cyfer13

+0

귀하의 답변 중 하나가 귀하의 질문에 도움이됩니까? 그렇다면, 당신은 받아 들여야합니다. – Andy

답변

1

당신은 방법 공공 재정을 IEnumerable RetrieveAll (IAuditSearch searchParameters)를 정의 할 수 없습니다

여전히 IAuditSearch 대신에 U 형 매개 변수를 사용해야합니다 방법. 발신자가 어떤 유형을 선택할지 결정합니다.

아마도 ISearch 인터페이스를 만들고 기본 클래스에 U : ISearch를 추가해야하지만 하위 클래스라도 IAuditSearch가 아닌 모든 ISearch 구현을 허용해야합니다.

아마도 가장 좋은 해결책은 RetreiveAll 메서드를 정의하는 IAuditSearch 저장소를 정의하는 것입니다.

편집 : 질문이 변경된 것으로 보입니다. 이제 두 방법 모두에서 동일한 문제가 발생합니다. 메서드를 재정의 할 때 사용할 인터페이스를 지정할 수 없으면 generic 형식 매개 변수를 유지 관리해야합니다.

public override IEnumerable<T> RetrieveAll<U>(U parameter1) { } 

public override bool Delete<U>(U parameter1) { } 

메서드에 where 절을 추가 할 수 없습니다. 이 경우 Liskov Substitution Prinicple이 발생합니다. 또한 나는 컴파일러가 그렇게 할 수 있을지조차 확신하지 못한다.

5

당신은 암시 적으로 (무시하지 않음으로써) 숨어 당신은 내 파생 클래스의 삭제 재산에 "새로운"키워드를 소개하는 오류를 극복 할 수

bool Delete<myType>(myType param) { ... } 

의 방법 서명. 이것은 명시 적으로 서명을 숨기고 모든 사람을 당신의 의도를 보여주는 것처럼 행복하게 만듭니다.

http://msdn.microsoft.com/en-us/library/aa691135%28v=vs.71%29.aspx에서 Microsoft 설명서를 참조하십시오.

+0

그것은 클래스의 다형성을 깨뜨리는 것처럼 나를 행복하게하지 않습니다. 이제 오버라이드 된 클래스에 대한 참조가 있으면 새로운 방식으로 작동하지만, 기본 유형으로 캐스트하면 이전 방식으로 동작합니다. 일반적으로 나는 회원 숨기기를위한'new' 키워드를 싫어합니다. –

+0

다형성을 유지하려면 "override"키워드 만 사용해야하며 개체를 캐스팅하여 기본 메서드에 액세스 할 수 있습니다. 숨어있는 것에 관해서는, 내가 보여주는 패턴을 모르지만, 이것은 명시 적으로 기본 파생어에 대한 액세스를 제거한다고 생각합니다. 왜? 나는 someones 예제를 듣고 싶다. –

+0

내가 잘못 입력했는데 오버라이드 된 것으로되어있었습니다. 위의 코드를 업데이트했습니다. – Cyfer13

0

불행하게도, 정확한 상황은 나에게 매우 명확하지 않습니다,하지만 난 당신의 코드는 다음과 같이한다고 생각 :

다른 IAuditSearch 구현은 "다른 매개 변수에 의해 검색"논리 incapsulate 것
public interface IParameter<T> { 
    bool Match(T entry); 
} 
public abstract class DataRepository<T, TParameter> 
    where TParameter : IParameter<T> { 
    public abstract IEnumerable<T> RetrieveAll(TParameter parameter1); 
    public abstract bool Delete(TParameter parameter1); 
} 
// 
public interface IAudit {/* ... */} 
public interface IAuditSearch : IParameter<IAudit> {/* ... */} 

public class SearchRepository : DataRepository<IAudit, IAuditSearch> { 
    public override bool Delete(IAuditSearch parameter1) { 
     // iterate by collection items using parameter matching 
     // CODE GOES HERE (DELETE ALL FOUND ENTRIES) 
    } 
    public override IEnumerable<IAudit> RetrieveAll(IAuditSearch parameter1) { 
     // iterate by collection items using parameter matching 
     // CODE GOES HERE (RETURN ALL FOUND ENTRIES) 
    } 
} 

:

var guidSearchResult = repository.RetrieveAll(
    new GuidSearch(new Guid("00000000-0000-0000-0000-000000000000"))); 
var idRangeSearchResult = repository.RetrieveAll(
    new IDRangeSearch(1000, 2000)); 
GuidSearch IDRangeSearch과 같이 구현된다

:

public class GuidSearch : IAuditSearch { 
    Guid ID; 
    public GuidSearch(Guid id) { 
     this.ID = id; 
    } 
    public bool Match(IAudit entry) { 
     /* search implementation using ID(Guid)*/ 
     throw new NotImplementedException(); 
    } 

} 
public class IDRangeSearch : IAuditSearch { 
    int StartID; 
    int EndID; 
    public IDRangeSearch(int startId, int endId) { 
     this.StartID = startId; 
     this.EndID = endId; 
    } 
    public bool Match(IAudit entry) { 
     /* search implementation using ID range (StartID...EndID)*/ 
     throw new NotImplementedException(); 
    } 
} 
+0

다른 매개 변수를 다른 메서드에 전달하려면 어떻게해야합니까? Guid 형의 매개 변수를 필요로하는 검색 메소드가 있다면? – Cyfer13

+0

@ Cyfer13 : 내 생각에 대한 자세한 설명으로 답변을 업데이트했습니다. 이 접근법이 귀하의 필요에 적합한 지 여부를 검토하고 알려주십시오. – DmitryG

0

다음 코드가 대신 작동합니까?

public class SearchRepository : DataRepository<IAudit, IAuditSearch> 
{ 
    public override IEnumerable<IAudit> RetrieveAll<IAuditSearch>(IAuditSearch searchParameters) 
    { 
     // CODE GOES HERE 
    } 

    public override bool Delete<TIAudit>(IAudit audit) 
    { 
     // CODE GOES HERE 
    } 
} 

public abstract class DataRepository<T, TSearch> 
{ 
    public virtual IEnumerable<T> RetrieveAll(TSearch parameter1) 
    { 
     throw new NotImplementedException(); 
    } 

    public virtual bool Delete(T parameter1) 
    { 
     throw new NotImplementedException(); 
    } 
} 

그래서 DataRepository의 모든 인스턴스를 위해, 우리는 결과 유형 (T), 및 검색 유형 (TSearch)를 선언합니다.

-C

+0

내가보기에 가장 큰 문제는 검색 매개 변수의 유효성을 검사 할 필요가 있다는 것입니다. RetrieveAll (guid x, guid y)이라면 두 값을 모두 입력했음을 알 수 있습니다. 그것이 검색 객체 인 경우 객체가 내부에 null이 아닌 것을 보장 할 수 없습니다. 그래서 당신은 어떤 종류의 iValidate가 필요합니다. – Cyfer13