Как добавить элементы в общую коллекцию? - PullRequest
3 голосов
/ 10 января 2012

Дано:

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

, за исключением c, не относится к типу <T>.

Итак, как мне добавить элемент в общую коллекцию?


i пробовал имея:

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

но я неиспользовать его, потому что никто не может позвонить DoStuff:

ICollection<Customer> c;
DoStuff(c); <---error

, потому что что-то о ковариации , а .NET не понимает, что Customer происходит от Human:

class Customer : Human {}

Ответы [ 3 ]

8 голосов
/ 10 января 2012

Точно так же вы знаете , почему вы получаете эту ошибку, 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);
}

но я просто хотел выбросить этот ответ, чтобы объяснить почему вы получаете эту ошибку. Подумайте об этом, если бы вы могли передать коллекцию Customer как коллекцию Human, это позволило бы вам добавить ЛЮБОГО вида человека, и это нарушило бы исходную коллекцию.

Таким образом, даже если Customer расширяет Human, это не означает, что ICollection<Customer> расширяет ICollection<Human> и ICollection<T> не является ковариантным / контравариантным, поскольку использует T как для in, так и out операции.

7 голосов
/ 10 января 2012

должно быть просто:

T t = new T();
....
source.Add(t);

Также вам нужно будет добавить ограничение new , чтобы гарантировать, что T имеет открытый конструктор без параметров:

public static void DoStuff<T>(ICollection<T> source) where T: new()
{
   //...
}
1 голос
/ 10 января 2012

Вы, вероятно, хотите что-то вроде этого:

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