views:

167

answers:

4

Hi, does anyone know if it is possible to cast a generic type with a certain type parameter (e.g. Bar) to the same generic type with the type parameter being a base type of Bar (such as object in my case). And, if it is possible, how would it be done?

What I want to do is have a collection of Foo<object> but be able to add Foos with more specific type arguments.

Thanks

+2  A: 

Use the ConvertAll method of List(T) or Array.

http://msdn.microsoft.com/en-us/library/73fe8cwf.aspx

vfilby
He didn't actually specify that he was working with `List<T>`, though...
Reed Copsey
He didn't really give any specifics. The ConvertAll function or List(T) or Array are exceptionally handy at these points even if you have to convert from one collection to another.
vfilby
+2  A: 

Yes it is possible in C# 4.0!

You should look into covariance.

m0sa
This is not correct. You should say "Yes, it is possible from C# 4 onwards".
Martinho Fernandes
And this was actually not what he was asking to do, if you read the text...
Reed Copsey
Ok, I edited my post.
m0sa
+3  A: 

You can have a collection of a base type with subclasses added. For example, the following will work:

// Using:
public class Foo {} // Base class
public class Bar : Foo {} // Subclass

// Code:
List<Foo> list = new List<Foo>();
HashSet<Foo> hash = new HashSet<Foo>();

list.Add(new Bar());
list.Add(new Foo());

hash.Add(new Bar());

Since "Bar" is a specific type of "Foo", it's perfectly legal to add it to a collection of Foo.

However, until .NET 4 and the out modifier for covariance, you cannot do:

IEnumerable<Foo> list = new List<Bar>(); // This isn't supported in .NET 3.5...
Reed Copsey
Actually, you can't do that in .NET 4 either. `IList<T>` is neither co- nor contravariant, because T shows up as both parameters (in Add) and return values (in the indexer). With `IEnumerable<T>` it works.
Martinho Fernandes
@Martinho: Yeah, true - I fixed it - thanks for pointing that out.
Reed Copsey