Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why generic extension method with constraint is not recognized as extension method? [duplicate]

Possible Duplicate:
No type inference with generic extension method

Consider two methods:

public static IEnumerable<V> Merge<V>
       (this IEnumerable<IEnumerable<V>> coll)

public static IEnumerable<V> Merge<T, V>
       (this IEnumerable<T> coll) 
              where T : IEnumerable<V>

Both compile just fine, in both cases the type of generic types will be known at compile time of caller, and thus the exact type of extended type.

You can call both fine, but only the first one as extension.

Why?

Update 1

To see it fail, use the second method and such example:

    var x = new List<List<int>>();
    var y = x.Merge();

Update -- closing

Don't you guys think the original post is WAY too elaborate to get the clear picture? For educational purposes I think this post shouldn't be closed, even if technically (i.e. the answer) it is duplicate. Just my 2 cents.

like image 965
greenoldman Avatar asked Aug 24 '11 17:08

greenoldman


2 Answers

Method type inference does not take constraints into account when making inferences.

This same question was asked yesterday. See my answer there for more details.

No type inference with generic extension method

like image 180
Eric Lippert Avatar answered Nov 04 '22 15:11

Eric Lippert


I don't think the problem is that the second CAN'T be called, but that IntelliSense won't see it because it can't easily infer the second generic type parameter V from your call without explicit help.

For example, given your two extension methods, the following are all legal

    // IEnumerable<IEnumerable<int>> definition...
    List<List<int>> x = ...;

    // calls your first method (implicitly)
    x.Merge();

    // also calls your first method (explicitly)
    x.Merge<int>();

    // calls your second method (explicitly)
    x.Merge<List<int>, int>();

All three of these compile successfully, I just think with the two generic type parameters, it can't infer your second generic type parameter from usage and thus it's not showing in intellisense, but still legal...

UPDATE: As per the asker, it's not that the two methods were declared as overloads, but that they were either/or. Given that reason Merge() doesn't work on the 2nd form because the relationship between T and V are defined in the type constraints, and thus are not used for type inference as Eric stated in his S.O. answer.

like image 2
James Michael Hare Avatar answered Nov 04 '22 16:11

James Michael Hare