I’m banging my head against generics here. It’s a major mind job to understand generics fully.
Take this example that stumped me. I have a type, let’s call him Foo, that is a generic type: Foo<T>. T has to be a subclass of the abstract Stream class. So we have:
[csharp]public class Foo
Now, in some other class, I have a method (SomeMethod) that wants to return an unspecified type of Foo<T>. And first at runtime will I decide if I want to return an FileStream or an MemoryStream. Like:
[csharp]public Foo
if (m_iFeelLikeIt)
return new Foo
else
return new Foo
}[/csharp]
You’d think this would work correctly, right? Wrong! The compiler says:
Cannot implicitly convert type ‘Foo<FileStream>’ to ‘Foo<Stream>’
For our simple brains, since you can cast an FileStream to a Stream, you should be able to cast a Foo<FileStream> to a Foo<Stream>, but this is not the case – not implicitly nor explicitly. What you have to do is create a base class for Foo that is not generic. You can then write your method like this:
[csharp]public abstract class Foo {}
public class Foo
public Foo SomeMethod() {
if (m_iFeelLikeIt)
return new Foo
else
return new Foo
}[/csharp]
Now all compiles and is goodness. If my examples don’t help you grok, read more on this subject here: Rick Byers : Generic type parameter variance in the CLR.
Jeroen F wrote up a bit about co- and contravariance a while back:
http://weblog.ikvm.net/CommentView.aspx?guid=21f9ed86-827e-4666-9553-5d4a8d735b7e
It seems IL supports what you want to do, but not the C# language.
Left by Kim Gräsman on November 7th, 2005