Reputation: 256671
Given:
public static void DoStuff<T>(ICollection<T> source)
{
Customer c = new Customer();
....
source.Add(c);
}
except c
is not of type <T>
.
So how do i add an item to a generic collection?
i tried having:
public static void DoStuff(ICollection<Human> source)
{
Customer c = new Customer();
....
source.Add(c);
}
but i don't use it because nobody can call DoStuff
:
ICollection<Customer> c;
DoStuff(c); <---error
because something about covariance, and .NET doesn't realize that Customer
descends from Human
:
class Customer : Human {}
Upvotes: 3
Views: 5610
Reputation: 38397
Just so you know why you get that error, an ICollection<Customer>
can not be passed to an ICollection<Human>
because they are not the same thing. Think of it this way, if you had an ICollection<Human>
you could Add(new Deadbeat())
if Deadbeat
derived from Human
.
The other answers on ways to avoid your issue with a generic solves your problem (so they should get the answer credit):
public static void DoStuff<T>(ICollection<T> source) where T : new()
{
T c = new T();
...
source.Add(c);
}
but I just wanted to throw this answer out to explain why you get that error. Think of it, if you could pass a collection of Customer
as a collection of Human
, it would let you add ANY kind of human, and this would violate the original collection.
Thus, even though Customer
extends Human
, this does not mean that ICollection<Customer>
extends ICollection<Human>
and ICollection<T>
is not covariant/contravariant because it uses T
for both in
and out
operations.
Upvotes: 8
Reputation: 463
You probably want something like this:
public static void DoStuff<T>(ICollection<T> source)
where T : new()
{
T c = new T();
source.Add(c);
}
Upvotes: 1
Reputation: 160882
should be just:
T t = new T();
....
source.Add(t);
Also you will have to add the new
constraint to guarantee that T
has a public parameterless constructor:
public static void DoStuff<T>(ICollection<T> source) where T: new()
{
//...
}
Upvotes: 7