I have a piece of code that works like this:
public IEnumerable<ICacheMember> Flubvert( IEnumerable<ICacheMember> members )
{
// do some stuff to members
return members;
}
However I am confused as to why I can't do this:
public IEnumerable<T> ExecuteFlubversion<T>( IEnumerable<T> memberList ) where T: class,ICacheMember
{
return Flubvert( memberList );
}
Surely the constraint on the generic should guarantee that memberList
is an IEnumerable of the ICacheMember
type? Do I really need to convert a collection of existing ( but implicit ) ICacheMember
objects into explicit ICacheMember
objects and then convert them back afterwards? I can understand that I might need to convert them back given the method signature of Flubvert
but I don't see why I should have to convert them in the method call. This is what I am doing in the working code but it seems completely out of keeping with the generally elegant behaviour of generics so I think I must be misunderstanding something about how this is supposed to operate.
First of all covariance of IEnumerable<out T>
(and other generic types) only works when T
is a reference type, so you need:
public IEnumerable<ICacheMember> ExecuteFlubversion<T>(IEnumerable<T> memberList)
where T: class, ICacheMember // NOTE 'class'
{
var flub = Flubvert(memberList); // can you call with 'memberList'?
return flub; // can you return that type?
// depending on what 'Flubvert' does, maybe return 'IEnumerable<T>'
// and say:
// return (IEnumerable<T>)flub;
}
Also note that I changed the return value. The C# compiler cannot guarantee that the returned object from the non-generic Flubvert
method is anything more specific than IEnumerable<ICacheMember>
.