Method resolution says that closer is better. See the blog post for exact rules.
What does the closer mean? Compiler will see if it can find exact match, if it can't find for some reason it will find next possible compatible methods and so forth.
Let's first make that method compile by removing the SomeInterface
constraint.
public static class ExtensionMethods
{
public static void Method<T>(this T parameter) //where T : SomeInterface
{ }
public static void Method<T>(this IEnumerable<T> parameter) //where T : SomeInterface
{ }
}
Now compiler is happy to compile, and do note that both method calls Goes to Method(T)
rather than Method(IEnumerable<T>)
. Why is that?
Because Method(T)
is closer in the sense that can take any type as the parameter and also it doesn't require any conversion.
Why is Method(IEnumerable<T>)
not closer?
It is because you have the compile time type of the variable as List<T>
, so it needs a reference conversion from List<T>
to IEnumerable<T>
. Which is closer but far from doing no conversions at all.
Back to your question.
Why instances.Method();
doesn't compile?
Again, as said earlier to use Method(IEnumerable<T>)
we need some reference conversion, so obviously that's not closer. Now we're left with only one method which is very closer is Method<T>
. But the problem is you have constrained it with SomeInterface
and clearly List<SomeImplementation>()
is not convertible to SomeInterface
.
The problem is (am guessing) checking for generic constraints happens after the compiler chooses the closer overload. That invalidates the chosen best overload in this case.
You could easily fix it by changing the static type of the variable to IEnumerable<SomeImplementation>
that will work and now you know why.
IEnumerable<SomeImplementation> instances = new List<SomeImplementation>();
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…