2012-01-26 2 views
10

私の問題がどのように呼ばれているかわからないので、誰も同じ質問を最近または全く質問していないことを保証することはできません。ジェネリックと継承について(私の悪いタイトルを許して)

私は気付きましたが、同様のタイトルのスレッドがかなりありますが、私の問題には関係していないようです。

私はジェネリックスを実装するカスタムリストクラスを持っています。

class MyList<T> 
{ 
    public void add(T item) // adds an item to the list 
    { /* code */ } 
    public void add(MyList<T> list) // attaches an existing list to the end of the current one 
    { /* code */ } 
} 

私も授業があります。

class Apple : Fruit 

class Banana : Fruit 

を今、関連するコードを付属しています。

MyList<Fruit> fruitList = new MyList<Fruit>(); 
// fill fruitList 

fruitList.add(new Apple()); // works, of course 
fruitList.add(new Banana()); // works as well, of course 

MyList<Apple> appleList = new MyList<Apple>(); 
// fill appleList 

fruitList.add(appleList); // doesn't work. Why? 

appleListがMYLISTですが(うちアップル)とアップルはフルーツ、VisualStudioはaccepしないMyList(Of Apple)の引数としてMyList(Of Fruit)が尋ねられます。私はこのようなリストを宣言した場合

しかし、:

MyList<object> fruitList = new MyList<object>(); 

はその後、すべてが再び動作します。私は間違って何をしたのですか?

回答が大変ありがとうございます。また、お返事いただいても、お返事ありがとうございます。

+1

FYI、.NETで4.0 IEnumerableインターフェイスは、それの型パラメータTに共変であるという理由だけで、これは定義は次のようになりますこれに関する主なキーワードは、共分散、反分散、不変性です。はい、あなたがそれについて知らない時に見つけるのはむしろ難しいです。 – delnan

+2

'IList 'を実装するべきです。 – SLaks

+0

.Netのパブリックメンバー名はUpperCamelCaseである必要があります。 – SLaks

答えて

8

covarianceを使用しようとしています。
.Netはインターフェイス上の一般的な分散のみをサポートしているため、動作しません。

さらに、共分散は、不変型に対してのみ意味を持ちます。
MyList<Fruit>に変換できた場合、タイプセーフティに違反してOrangeをリストに追加することができます。

代わりに、あなたは方法は、一般的なことができます:

public void Add<U>(IList<U> list) where U : T 
3

私はIMyListインターフェースの設計がされるべきだと思う:予想通り

public interface IMyList<T> : IEnumerable<T> 
{ 
    void Add(T item); 
    void AddRange(IEnumerable<T> itemList); 
} 

すべてが動作します。どうして?

public interface IEnumerable<out T> : IEnumerable 

IMyListインターフェース(リストデコレータ)のシンプルな実装:

public class MyList<T> : IMyList<T> 
{ 
    private readonly List<T> _list = new List<T>(); 

    #region Implementation of IMyList<in T> 

    public void Add(T item) 
    { 
     Console.WriteLine("Adding an item: {0}", item); 
     _list.Add(item); 
    } 

    public void AddRange(IEnumerable<T> itemList) 
    { 
     Console.WriteLine("Adding items!"); 
     _list.AddRange(itemList); 
    } 

    #endregion 

    #region Implementation of IEnumerable 

    public IEnumerator<T> GetEnumerator() 
    { 
     return _list.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    #endregion 
} 
+0

+1優れたデザインを提案する – phoog

関連する問題