Reputation: 13187
Consider the following example:
class Base {}
class Derived : Base {}
class Test1
{
private List<Derived> m_X;
public IEnumerable<Base> GetEnumerable()
{
return m_X;
}
}
This compiles just fine, because IEnumerable<T>
is covariant in T
.
However, if I do exactly the same thing but now with generics:
class Test2<TBase, TDerived> where TDerived : TBase
{
private List<TDerived> m_X;
public IEnumerable<TBase> GetEnumerable()
{
return m_X;
}
}
I get the compiler error
Cannot convert expression type 'System.Collection.Generic.List' to return type 'System.Collection.Generic.IEnumerable'
What am I doing wrong here?
Upvotes: 15
Views: 933
Reputation: 9800
Thing is, in the first case, the Base
is known to be a class. In the second case, the type parameter T
could be either class or a struct (this is how compiler thinks).
Solve the case by specifying that T
is a class, and the error will disappear:
class Test2<TBase, TDerived> where TDerived : class, TBase
{
private List<TDerived> m_X;
public IEnumerable<TBase> GetEnumerable()
{
return m_X;
}
}
So, the compiler tries to show us that TDerived could be a struct (since you didn't specify class
constraint) and as we already know, covariance and contravariance do not work with structs.
Upvotes: 14