16

コード スニペットを検討してください。

IList<String> obj=new List<string>();
IEnumerable<Object> obj1 = obj;

しかし、私が書くICollection<Object> obj2 = obj;と、コンパイル時エラーが発生します。

System.Collections.Generic.IList<string>タイプ ' ' を ' ' に暗黙的に変換することはできませんSystem.Collections.Generic.ICollection<object>

andと andList<T>の両方を実装しているため、この動作はなぜですか?IEnumerable<T>ICollection<T>IList<T>

public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable
{
    T this[int index] { get; set; }
    int IndexOf(T item);
    void Insert(int index, T item);
    void RemoveAt(int index);
}
4

2 に答える 2

20

ICollection<T>は型パラメーターで共変ではありませんが、共変IEnumerable<T>です。それらの宣言 ( ICollectionIEnumerable ) を見ると、キーワード onをIEnumerable<T>使用しているのに対し、使用していないことがわかります。outTICollection<T>

考えてみれば、これは理にかなっています。インターフェイスがオブジェクト (したがってキーワード)を読み取るためだけに使用される場合、(大まかに言えば) 共分散は安全だからです。は明らかにその基準を満たしていますが、まったく逆です。outIEnumerable<T>ICollection<T>

何がうまくいかないかの例として(あなたの例を使用して):

IList<String> obj = new List<string>(); // Legal, of course
ICollection<Object> obj1 = obj;         // Illegal, but let's see what happens
obj1.Add(new NonStringObject());        // That's not a string being stored in a List<string>

注意: 共分散は継承と同じではありません。2 つのクラスまたはインターフェイスが継承関係を共有しているからといって、それらの型パラメーターが同じ分散特性を共有しているとは限りません。

于 2011-07-16T13:48:04.367 に答える