2012-02-08 3 views
0

다음은 상황을 재현하려는 나의 최선의 시도입니다.일반 콜렉션

public interface IFoo 
{ 

} 

public class Foo : IFoo { } 

public class Bar : IFoo { } 

public class CollectionOf<T> : List<IFoo> 
{ 

} 

public class Bars : CollectionOf<Bar> 
{ 

} 

public class Test 
{ 
    public void Test() 
    { 
     CollectionOf<IFoo> bars = new Bars(); 
    } 
} 

컴파일러는 인스턴스화에 불만을 표시합니다. Bars는 IFoos 컬렉션입니다. 이 공분산/반항성 문제 중 하나입니까?

+0

감사합니다. @EdS. 수정 프로그램은 무엇입니까? – Matthew

+0

공분산/반항을 지원하려면 CollectionOf가 콜렉션에서 읽거나 콜렉션에 추가하는지 여부를 알아야합니다. 둘 다있을 수없고 공분산 또는 반항을 여전히 지원할 수는 없습니다. – Lukazoid

답변

1

수정 사항이있는 경우 수정 내용은 작동하지 않는 부분에 따라 다릅니다. 예제를 두 가지 방법으로 컴파일 할 수 있습니다. IEnumerable을 사용하거나 CollectionOf를 out 제네릭 수정자를 가진 인터페이스로 정의하십시오. 여부는 당신을위한 수정인지 모르겠습니다.

public interface IFoo { } 

public class Foo : IFoo { } 

public class Bar : IFoo { } 

public interface CollectionOf<out T> : IEnumerable<IFoo> { } 

public class Bars : CollectionOf<Bar> { } 

public class Test 
{ 
    public void Test() 
    { 
     IEnumerable<IFoo> bars1 = new Bars(); 
     CollectionOf<IFoo> bars2 = new Bars(); 
    } 
} 
+0

나는 이것이 내가 찾고있는 것이라고 생각한다. CollectionOf에서 제거해야하므로 필요한 것은 내가 필요로하는 것입니다. – Matthew

2

예입니다.

허용 된 경우 IFoo 인터페이스를 구현하는 한 컬렉션에 개체를 둘 수 있지만 컬렉션에는 안전하지 않습니다.

나를 설명하자 :이 시점에서

var b = new Bars(); 
CollectionOf<IFoo> bars = b; 
bars.Add(Dummy); // implements IFoo, but does not descend from Bar 

b 무엇을 포함 하는가? 유형이 Dummy 인 객체입니까? 그것은 나쁘고, 따라서 이것은 처음부터 허용되지 않습니다.

+0

빠른 손가락을 젠장 .... –

+0

고맙습니다. 그렇습니다. 이 (가) 재생하려면 어떻게해야합니까? – Matthew

+1

''또는 _covariance_는 클래스'Foo '의 요소가 상영되었음을 의미합니다. 예를 들어,'Foo myFoo = new Foo ();'. 이 상황에서'T'는 리턴 타입에서만 사용할 수 있습니다 (따라서 out). 자세한 내용은이 [link] (http://msdn.microsoft.com/en-us/library/ee207183.aspx)를 확인하십시오. – Lukazoid

4

예.

잠시 생각해보십시오. barsIFoo을 구현하는 모든 유형의 객체를 합법적으로 보유 할 수 있어야합니다. 그러나 Bars 유형의 객체는 Bar 유형의 객체 만 보유 할 수 있습니다.

코드를 사용하면이 작업이 허용됩니다. 이는 분명히 잘못되었습니다.

CollectionOf<IFoo> bars = new Bars(); 
bars.Add(new Foo()); // Uh oh! 

그러면 제네릭을 통해 제공되는 유형 안전성이 효과적으로 저하됩니다.

+0

해당 모음에 막대를 넣을 것이라고 약속하면 어떻게됩니까? 또는 은 무엇에 관한 것입니까? – Matthew

+0

'Bar' 만 콜렉션에 넣고 싶다면'CollectionOf bars = new Bars();'를 사용하지 않으시겠습니까? – Lukazoid

+0

@Matthew : 아니요, 잘못된 행동을 허용하지 않습니다. 인터페이스를 통해서만 작업하지 않는 한'Foo'를'Bar' 컬렉션에 추가 할 수 없습니다. 이것은 C++가 아닙니다. 제네릭은 강력하게 입력됩니다. 당신의 예를 형성 할 수있는 상황은 의미가없고 표준에 정의되지 않은 행동을 야기 할 것입니다. –