-3

今日、共分散と反分散について調べていたところ、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>ですか?

以下のマットに感謝します。参照型を扱っていることを覚えておくと役立ちます。これを永遠に反対票を投じてください。

4

1 に答える 1

1

あなたが見逃しているのは、最初の例で行うときだと思います:

List<Fruit> fruitBowl = bunchOfBananas;

のコピーを に作成していませ。代わりに、バナナの束への参照を作成しており、その参照を使用してあらゆる種類の果物を追加できます。bunchOfBananasList<Fruit>

したがって、次の場合:

fruitBowl.Add(new Apple());

果物のリストにリンゴを追加することはありません。にリンゴを追加することになりますがList<Banana> bunchOfBananas、これは明らかに悪いことです。

于 2013-05-01T13:10:36.807 に答える