匹配错误的扩展方法

时间:2011-01-31 20:00:44

标签: linq c#-3.0 extension-methods

我有这些扩展方法:

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>。)

我做错了很明显吗?

3 个答案:

答案 0 :(得分:1)

SelectedValueswells的声明类型是什么?扩展方法在编译时绑定,而不是在运行时绑定,因此重要的是编译时类型。

修改:由于您说SelectedValues被声明为IList类型,因此唯一可能用作您提供的三个SelectedValues的扩展方法

public static void Replace<T>(this IList list, T newItem)

然后,编译器意识到它可以将wells视为TTwells的声明类型,然后可以调用方法

public static void Replace<T>(this IList list, T newItem)

其中SelectedValues填写参数listwells填写参数newItem,声明的wells类型填写类型参数T。这就是调用扩展方法的原因。

同样,扩展方法在编译时绑定。如果要调用其他方法,则需要为SelectedValues使用不同的声明类型。

因此,这不是编译器“匹配错误的扩展方法”的情况,这是编译器匹配唯一可能的扩展方法的情况。此行为是设计使然;这是一个功能,而不是一个错误。

答案 1 :(得分:0)

我不记得过载偏好的规则,但作为一个解决方案,指定一个(多余的)强制转换通常会修复这些:

SelectedValues.Replace((IEnumerable<IWell>)wells);

答案 2 :(得分:0)

这里有趣的类型不是SelectedValues,而是wells - TIEnumerableIEnumerable<T>是哪个?如果您总是点击第一种方法,wells可能只是一个T实例,尽管它的名称是复数形式。

此外,很高兴知道完全类型SelectedValues是什么 - 它实现IList<IWell>的事实并不能阻止它实现IList同样。

相关问题