我有这些扩展方法:
public static void Replace<T>(this 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 )
我有一个Linq语句,产生一个名为IList<IWell>
的井。 (我在运行时确认井是IEnumerable<IWell>
。)
然而,声明
SelectedValues.Replace( wells );
始终点击第一个扩展方法,而不是第二个或第三个。 (我在运行时确认SelectedValues为IList<IWell>
。)
我做错了很明显吗?
答案 0 :(得分:1)
SelectedValues
和wells
的声明类型是什么?扩展方法在编译时绑定,而不是在运行时绑定,因此重要的是编译时类型。
修改:由于您说SelectedValues
被声明为IList
类型,因此唯一可能用作您提供的三个SelectedValues
的扩展方法
public static void Replace<T>(this IList list, T newItem)
然后,编译器意识到它可以将wells
视为T
,T
是wells
的声明类型,然后可以调用方法
public static void Replace<T>(this IList list, T newItem)
其中SelectedValues
填写参数list
,wells
填写参数newItem
,声明的wells
类型填写类型参数T
。这就是调用扩展方法的原因。
同样,扩展方法在编译时绑定。如果要调用其他方法,则需要为SelectedValues
使用不同的声明类型。
因此,这不是编译器“匹配错误的扩展方法”的情况,这是编译器匹配唯一可能的扩展方法的情况。此行为是设计使然;这是一个功能,而不是一个错误。
答案 1 :(得分:0)
我不记得过载偏好的规则,但作为一个解决方案,指定一个(多余的)强制转换通常会修复这些:
SelectedValues.Replace((IEnumerable<IWell>)wells);
答案 2 :(得分:0)
这里有趣的类型不是SelectedValues
,而是wells
- T
,IEnumerable
或IEnumerable<T>
是哪个?如果您总是点击第一种方法,wells
可能只是一个T
实例,尽管它的名称是复数形式。
此外,很高兴知道完全类型SelectedValues
是什么 - 它实现IList<IWell>
的事实并不能阻止它实现IList
同样。