Circleオブジェクトの配列があります(CircleはIShapeインターフェイスを実装し、パラメーターが..の関数を持っています。CirclesのList<IShape>
配列をこれに渡せないのはなぜですか?
Visual Studioで、に変換できないというビルドエラーが発生しList<Circle>
ますList<IShape>
Circleオブジェクトの配列があります(CircleはIShapeインターフェイスを実装し、パラメーターが..の関数を持っています。CirclesのList<IShape>
配列をこれに渡せないのはなぜですか?
Visual Studioで、に変換できないというビルドエラーが発生しList<Circle>
ますList<IShape>
簡単に言うと、関数は次のFoo
ように実装できるためです。
void Foo(IList<IShape> c)
{
c.Add(new Square());
}
にを渡した場合、型シグネチャが問題ないと主張していてもList<Circle>
、Foo
提供された型はを格納できません。共変ではありません:任意の形状の追加をサポートできないため、一般的なものはできません。Square
IList<T>
IList<Circle>
IList<IShape>
修正は、のIEnumerable<IShape>
引数を受け入れるために使用することFoo
ですが、すべての場合に機能するとは限りません。IEnumerable<T>
共変である:専門家IEnumerable<Circle>
は一般の契約に適合しIEnumerable<IShape>
ます。
この振る舞いも良いことです。あるべきではないのに共変であるものの典型的な例は配列です。次のコードはコンパイルされますが、実行時に失敗します。
void Bar()
{
// legal in C#:
object[] o = new string[10];
// fails with ArrayTypeMismatchException: can't store Int in a String[]
o[0] = 10;
}