2016-03-09 4 views
5

私は数日間共分散と反共分散を経験していますが、私は何かを理解していると思っていますが、私が現在の私の答えで肯定または否定を得ることができなかったので、研究。私は、次のクラス階層を持っている:私のここでの共分散についての理解が正しいかどうか確認するのを助けてください。

class Shape 
{ 
    public string Name { get; set; } 
} 
class Square : Shape 
{ 

} 

その後、これは私が使用してプログラムをスタートしました何私です:

List<Square> squares = new List<Square>() { new Square { Name = "Square One" }, new Square { Name = "Square Two" } }; 
IEnumerable<Square> squaresEnum = squares; 

は、今私が持っている二つの質問です:

は以下の通りであります可能IEnumerableを< T>は共変であるため、:

IEnumerable<Shape> shapesEnumerable = squares; 

AND、Fでありますあなたは、私が上だなら、私に知らせてできてください

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<Square> squares = new List<Square>() { new Square { Name = "Square One" }, new Square { Name = "Square Two" } }; 
     IEnumerable<Square> squaresEnum = squares; 

     /* Does this work because IEnumerable<T> is covariant? */ 
     IEnumerable<Shape> shapesEnumerable = squares; 

     /* Does this NOT work because List<T> is NOT covariant */ 
     //List<Shape> shapes = squares; 

     Console.ReadKey(); 
    } 
} 
class Shape 
{ 
    public string Name { get; set; } 
} 
class Square : Shape 
{ 

} 

:それは何のために必要な場合はここで

List<Shape> shapes = squares; 

は完全なプログラムコードです:リスト< T>は共変ではありませんので、ollowingことはできませんこれと正しい軌道?

+2

はい。それは正しいです。 – SLaks

+1

@SLaksありがとうございました! – macmatthew

答えて

2

はい、あなたは正しいです。

私たちはこの困難な状況を抱えている可能性があるので、このコードは許されませんでした。

我々はTHSのように新しいクラスを作成することができます。

クラストライアングル:形状{}

その後

IEnumerable<Shape> triangles = new List<Triangle>() 
{ 
     new Triangle { Name = "Triangle One" }, 
     new Triangle { Name = "Triangle Two" } 
}; 

そして今、この場合は、許容できる場合

List<Shape> squares = new List<Square> { ... }; 

このように開発することができます

squares.AddRange(triangles); 

またはこのような問題があります。

ネットコンパイラは非常に賢いです:)

1

これは、共分散の良いケースです。 IEnumerable<T>Tout Tと定義するので、IEnumerable<Square>IEnumerable<Shape>に割り当てることができます。 List<T>でこれを行うことができない理由は、それがインターフェイスではなく、インターフェイスだけが共変動および反競合を宣言できることです。

また、List<T>は、入力としても使用されるので、Tを共変にすることは意味がありません。これは、Arlyom Tonoyanの例で強調されています。 IEnumerable<T>は、出力としてのみ使用されるため、そのまま定義することができます。

関連する問題