Why is IEnumerable(of T) not accepted as extension method receiver
Consider this:
public struct ValueElement : ITest { }
and this:
IEnumerable<ValueElement> collection = ...
collection.Method(); //OK, ValueElement implement ITest, as required.
collection.ToInfoObjects() //Error, IEnumerable<ValueElement> is not IEnumerable<ITest>
//variance does not work with value types.
So that not every type allowed for Method
also allowed for ToInfoObjects
. If you add class
constraint to T
in Method
, then your code will compile.
Related videos on Youtube
Kornelije Petak
EDU: MSc.IT @ Faculty of Electrical Engineering and Computing, University of Zagreb, Croatia
Updated on June 22, 2022Comments
-
Kornelije Petak almost 2 years
Complete question before code:
Why is
IEnumerable<T>
where T : ITest
not accepted as receiver of an extension method that expectsthis IEnumerable<ITest>
?And now the code:
I have three types:
public interface ITest { } public class Element : ITest { } public class ElementInfo : ITest { }
And two extension methods:
public static class Extensions { public static IEnumerable<ElementInfo> Method<T>( this IEnumerable<T> collection) where T : ITest { → return collection.ToInfoObjects(); } public static IEnumerable<ElementInfo> ToInfoObjects( this IEnumerable<ITest> collection) { return collection.Select(item => new ElementInfo()); } }
The compiler error I get (on the marked line):
CS1929
:'IEnumerable<T>'
does not contain a definition for'ToInfoObjects'
and the best extension method overload'Extensions.ToInfoObjects(IEnumerable<ITest>)'
requires a receiver of type'IEnumerable<ITest>'
Why is this so? The receiver of the
ToInfoObjects
extension method is anIEnumerable<T>
and by the generic type constraint,T
must implementITest
.Why is then the receiver not accepted? My guess is the covariance of the
IEnumerable<T>
but I am not sure.If I change
ToInfoObjects
to receiveIEnumerable<T> where T : ITest
, then everything is ok. -
Kornelije Petak about 8 yearsThanks for your suggestion, but I know what I can do to solve the problem, and even more, I have written it in the original post. What I wanted is to know why the problem happens, not how to solve it.
-
Chris Wohlert about 8 years@KornelijePetak Oh, sorry for not paying enough attention to your question.
-
Kornelije Petak about 8 yearsNow that you've said it, it seems obvious to me. T could have been the value type and of course it wouldn't work. Thank you very much. As a follow up, I would like to link to the reason why co(ntra)variance does not work with value types.