如何管理C#Generics类,其中类型是基类的容器?

0 c# generics collections

我收到以下错误

`System.Collections.Generic.List> .Add(MyContainer)'的最佳重载方法匹配有一些无效参数(CS1502)(GenericsTest)

对于以下课程:

A和B是MyBase的子类.

public class GenericConstraintsTest
{

    private MyList<MyContainer<MyBase>> myList = new MyList<MyContainer<MyBase>>();

    public GenericConstraintsTest ()
    {
        MyContainer<A> ca = new MyContainer<A>(new A());

        this.Add<A>(new A());
        this.Add<B>(new B());
    }


    public void Add<S> (S value) where S : MyBase
    {
        MyContainer<S> cs = new MyContainer<S>(value);
        myList.Add(cs);    
    }


    public static void Main()
    {
        GenericConstraintsTest gct = new GenericConstraintsTest();
    }
}
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

干杯

Sve*_*ven 6

你试图myList.Add用a MyContainer<A>和a MyContainer<B>分别打电话.两者都不可转换为MyContainer<MyBase>因为具有不同泛型类型参数的两个泛型实例化总是不相关的,即使类型参数是相关的.

执行此操作的唯一方法是创建IMyContainer<out T>协变通用接口.这将允许你转换IMyContainer<A>IMyContainer<MyBase>if A来自MyBase.(注意:只有接口可以有协变和逆变类型参数,这仅在.Net 4中可用).

例如:

public interface IMyContainer<out T> { }
public class MyContainer<T> : IMyContainer<T> 
{
    public MyContainer(T value) { }
}
public class MyBase { }
public class A : MyBase { }
public class B : MyBase { }

public class GenericConstraintsTest
{

    private List<IMyContainer<MyBase>> myList = new List<IMyContainer<MyBase>>();

    public GenericConstraintsTest()
    {
        MyContainer<A> ca = new MyContainer<A>(new A());

        this.Add<A>(new A());
        this.Add<B>(new B());
    }


    public void Add<S>(S value) where S : MyBase
    {
        MyContainer<S> cs = new MyContainer<S>(value);
        myList.Add(cs);
    }


    public static void Main()
    {
        GenericConstraintsTest gct = new GenericConstraintsTest();
    }
}
Run Code Online (Sandbox Code Playgroud)