如何将项目添加到通用集合?

Ian*_*oyd 3 c# collections generic-collections

鉴于:

public static void DoStuff<T>(ICollection<T> source)
{
    Customer c = new Customer();
    ....
    source.Add(c);
}
Run Code Online (Sandbox Code Playgroud)

除了c不是类型<T>.

那么如何将项目添加到通用集合中?


试过:

public static void DoStuff(ICollection<Human> source)
{
    Customer c = new Customer();
    ....
    source.Add(c);
}
Run Code Online (Sandbox Code Playgroud)

但我不使用它,因为没有人可以打电话DoStuff:

ICollection<Customer> c;
DoStuff(c); <---error
Run Code Online (Sandbox Code Playgroud)

因为有关协方差的东西,并且.NET没有意识到Customer来自Human:

class Customer : Human {}
Run Code Online (Sandbox Code Playgroud)

Jam*_*are 8

只是你知道为什么你会得到那个错误,ICollection<Customer>不能传递给一个ICollection<Human>因为它们不是同一个东西.想想这样说,如果你有一个ICollection<Human>,你可以Add(new Deadbeat()),如果Deadbeat衍生Human.

关于避免使用泛型问题的方法的其他答案可以解决您的问题(因此他们应该得到答案):

public static void DoStuff<T>(ICollection<T> source) where T : new()
{
    T c = new T();
    ...
    source.Add(c);
}
Run Code Online (Sandbox Code Playgroud)

但我只是想抛出这个答案来解释你为什么会得到这个错误.想想看,如果你可以传递一个集合Customer作为集合Human,它会让你添加任何类型的人类,这将违反原始集合.

因此,即使Customer扩展Human,这并不意味着ICollection<Customer>扩展ICollection<Human>并且ICollection<T>不是协变/逆变,因为它T用于两者inout操作.


Bro*_*ass 7

应该只是:

T t = new T();
....
source.Add(t);
Run Code Online (Sandbox Code Playgroud)

此外,您还必须添加new约束以保证T具有公共无参数构造函数:

public static void DoStuff<T>(ICollection<T> source) where T: new()
{
   //...
}
Run Code Online (Sandbox Code Playgroud)