Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is IEnumerable(of T) not accepted as extension method receiver

Complete question before code:

Why is IEnumerable<T> where T : ITest not accepted as receiver of an extension method that expects this 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 an IEnumerable<T> and by the generic type constraint, T must implement ITest.

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 receive IEnumerable<T> where T : ITest, then everything is ok.

like image 619
Kornelije Petak Avatar asked Jan 29 '16 09:01

Kornelije Petak


1 Answers

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.

like image 56
user4003407 Avatar answered Sep 21 '22 21:09

user4003407