아래 계층 구조에서 IFoos를 허용하면서 컴파일 할 때 IBars를 제외하는 방법이 있습니까?컴파일 타임 제한 : B가 아닌 A를 허용합니다. B : A
예 :
//IFoo defines functionality that Snafu needs to use, and so is a type restriction.
public interface IFoo {...}
//IBar defines supplemental required functionality that Snafu does not support.
public interface IBar:IFoo {...}
//Can I generate a compiler error if an IBar is used as the generic type?
public class Snafu<T> where T:IFoo
{
public void DoSomethingWith(T myFoo)
{
//Best thing I can think of with the current hierarchy
if(myFoo is IBar) throw new ArgumentException("IBars are not supported");
}
}
내가 그 작동 생각할 수있는 유일한 것은 세 번째 "플래그"인터페이스를 정의하고, IBars 아닌 모든 IFoos에 적용하는 것입니다. IFoo 및 IBar를 정의한 경우 :
public interface IAmNotAnIBar:IFoo {}
public class Snafu<T> where T:IAmNotAnIBar {...}
그러나이 경우 해킹과 같은 냄새가납니다. 새로운 인터페이스는 IFoo가 아닌 새로운 것을 정의하지 않으며, 개발자는 IFoo (IIRC를 사용할 수 없다는 것을 알고 있어야합니다. IFoo를 숨기고 다른 인터페이스를 공용으로 노출시킴으로써 IFoo를 숨길 수는 없습니다.) IFoo를 구현하여 좋거나 나쁜 믿음으로 컴파일 타임 검사를 우회하십시오. 더 우아한 것이 있습니까?
편집 : 지금까지 모든 응답에 감사드립니다. 아마 더 구체적인 예가 제가 처음에 왜 질문을했는지 설명 할 수 있습니다.
IFoo는 DB에 매핑되는 도메인 개체의 기본 기능을 정의한다고 가정 해 보겠습니다. 읽기/쓰기 ID 속성이 있어야합니다. 어쩌면 DTO를 방출하고 흡수 할 수있는 능력이 있어야합니다. 위의 예에서 Snafu 클래스를 처리 할 수있는 Repository를 사용하여 IFoos를 영구 저장소에 읽고 쓰며 DoSomething()은 일부 영구적 인 작업을 수행합니다. 강력하게 형식화 된 IFoo에서).
이제 IBar를 IFoos와는 다른 방식으로 채워지는 도메인 개체로 정의 해 보겠습니다. 이들은 IFoo 기능 외에도 일관된 상태를 유지하는 몇 가지 추가 Initialize() 메서드를 정의합니다. 그것들은 여전히 도메인 객체 (IFoos)이며 Snafu가 메소드를 적절하게 호출 할 수 없기 때문에 IBar를 Snafu의 인스턴스에 전달할 수없고 정확한 결과를 기대할 수 없다는 점을 제외하면 시스템의 모든 영역에서 그대로 취급되어야합니다 (Initialize()가 Snafu가 가지고 있지 않으며 주어서는 안되는 외부 종속성 인 매개 변수를 취한다고 가정 해 봅시다). 대신 모든 IBars의 저장소 인 다른 클래스를 호출해야합니다. 내 목표는 컴파일 타임에 Snafu에서 DoSomething()에 대한 모든 가능한 호출의 적절한 런타임 테스트 (유닛, 통합, 기능, 수동 등)에 의존하는 대신 개발자가 뭔가 잘못하고 있음을 알리는 것이 었습니다. 그것이 IBar를 결코 통과하지 못하도록합니다.
'IFoo'는 * 유일한 * 허용 가능한 타입인가? 아니면' IBar가 허용되는 경우? –
IBar가 IFoo를 확장한다면 IFoo가하는 모든 일을 할 수있을뿐만 아니라 추가 작업도 할 수 있습니다 .IFoo가 예상되는 곳에서 IBar를 사용할 수없는 경우 IBar는 실제로 IFoo를 확장해서는 안됩니다. [Liskov 대체 원칙] (http : //en.wikipedia.org/wiki/Liskov_substitution_principle) – dtb
@dtb : 첫 번째와 두 번째 부분에 동의하지만 첫 번째 부분은 반드시 두 번째 부분을 의미하지는 않습니다. ar은 IFoo가하는 모든 작업을 수행하지만 특정 상황에서 사용해야하는 추가 기능을 제공합니다.이러한 이유로 IBar는이 상황에서 IFoo로 사용할 수 없습니다 (예, LSP에 위배됩니다). – KeithS