Matching wrong Extension method
I have these Extension methods:
public static void Replace<T>(thi开发者_StackOverflows IList list, T newItem)
public static void Replace<T>(this IList<T> list, IEnumerable newItems)
public static void Replace<T>( this IList<T> list, IEnumerable<T> newItems )
I have a Linq statement that produces an IList<IWell>
called, wells. (I confirm at runtime that wells is IEnumerable<IWell>
.)
However, the statement
SelectedValues.Replace( wells );
always hits the first extension method, not the second or third. (I confirm at runtime that SelectedValues is IList<IWell>
.)
Is it obvious what I am doing wrong?
What is the declared type of SelectedValues
and of wells
? Extension methods are bound at compile-time, not at runtime so it is the compile-time types that matter.
Edit: Since you said that SelectedValues
is declared as type IList
, the only possible candidate for use as an extension method on SelectedValues
of the three you provided is
public static void Replace<T>(this IList list, T newItem)
The compiler then realizes that it can consider wells
as a T
with T
being the declared type of wells
and then can invoke the method
public static void Replace<T>(this IList list, T newItem)
where SelectedValues
fills in for the parameter list
and wells
fills in for the parameter newItem
, and the declared type of wells
fills in for the type parameter T
. This is why that extension method is invoked.
Again, extension methods are bound at compile-time. If you want to invoke a different method, you need to use a different declared type for SelectedValues
.
So, this is not a case of the compiler "Matching wrong Extension method," this is a case of the compiler matching the only possible extension method. This behavior is by design; it is a feature, not a bug.
I can't remember the rules for overload preference, but as a solution, specifying a (superfluous) cast usually fixes these:
SelectedValues.Replace((IEnumerable<IWell>)wells);
The interesting type here is not SelectedValues
, but wells
- which of T
, IEnumerable
or IEnumerable<T>
is it? If you always hit the first method, it is likely that wells
, despite the plural form of it's name, is just a single T
instance.
Also, it would be nice to know exactly what type SelectedValues
is - the fact that it implements IList<IWell>
doesn't stop it from implementing IList
as well.
精彩评论