今日、共分散と反分散について調べていたところ、Jon Skeet がクラス レベルでの不変性を説明しているスタック交換に関する投稿に出くわしました。彼は果物の例を使用し、そのレベルで共分散を許可することがなぜ悪いことなのかを説明しました。
//Bad
List<Banana> bunchOfBananas = new List<Banana>();
// This would be valid if List<T> were covariant in T
List<Fruit> fruitBowl = bunchOfBananas;
fruitBowl.Add(new Apple());
Banana banana = bunchOfBananas[0];
では、Fruit から継承するクラスのインスタンスを追加するために、Fruit のリストがあることはどのように説明されるのでしょうか? 例えば:
//Good
List<Fruit> fruitBowl = new List<Fruit>();
fruitBowl.Add(new Apple());
fruitBowl.Add(new Banana());
過去にこれを行ったことがありますが、常に期待どおりに動作します。CLR が fruitBowl の型を調べないのはなぜですか? それは、最初に FruitBowl の値を Bananas のリストに設定し、それが Fruit のリストに対して共変であり、次にタイプが本当に であるコレクションに Apple を追加しようとしているからList<Banana>
ですか?
以下のマットに感謝します。参照型を扱っていることを覚えておくと役立ちます。これを永遠に反対票を投じてください。