tags:

views:

69

answers:

2

I think I must be missing something, why can't I compile this:

class Foo<T> where T : Bar
{
    T Bar;
}

abstract class Bar
{ }

class MyBar : Bar
{ }

static void Main(string[] args)
{
    var fooMyBar = new Foo<MyBar>();
    AddMoreFoos(fooMyBar);
}

static void AddMoreFoos<T>(Foo<T> FooToAdd) where T : Bar
{
    var listOfFoos = new List<Foo<Bar>>();
    listOfFoos.Add(FooToAdd); //Doesn't compile
    listOfFoos.Add((Foo<Bar>)FooToAdd); //doesn't compile
}
+3  A: 

It doesn't compile because if you were to call your method with a Foo<int> then the call will fail: you are trying to assume a specific type for your generic parameter.

What you need is to use var listOfFoos = new List<Foo<T>>() instead, then the Add should work.

(EDIT: equally, the cast would work if you used Foo<T> - but you still can't assume in your code that T is Bar).

Dan Puzey
'if you were to call your method with a Foo<int> then the call will fail' => but this call would not compile because of the generic constraint, where T : Bar, no? However, +1 for new List<Foo<T>>() as this actually solves my real problem!
Noel Kennedy
Good point on the constraint. Confused as to why you accepted the other answer if I solved your problem tho... (Jon Skeet or not! ;-))
Dan Puzey
+7  A: 

You're make things a little bit more confusing than they need to be by using a list here... it's easiest to see the effect this way:

// This won't compile
Foo<Bar> fooBar = new Foo<MyBar>();

Given that this doesn't compile, it's then not surprising that you can't add a Foo<MyBar> to a List<Foo<Bar>>

So why isn't a Foo<MyBar> a Foo<Bar>? Because generic classes aren't covariant.

Generic variance was only introduced in C# 4 - and it only works for interfaces and delegates. So you could (in C# 4) do:

IEnumerable<MyBar> x = new List<MyBar>();
IEnumerable<Bar> y = x;

but you couldn't do:

IList<MyBar> x = new List<MyBar>();
IList<Bar> y = x;

I have a whole talk about variance which you can download from the NDC 2010 video site - just search for "variance".

Jon Skeet