给定(非常简单的)代码。
public class Class1
{
}
public class Class2 : Class1
{
}
public class List1 : System.Collections.Generic.IEnumerable<Class1>
{
public new System.Collections.Generic.IEnumerator<Class1> GetEnumerator()
{
yield return new Class1();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
public class List2 : List1 , System.Collections.Generic.IEnumerable<Class2>
{
public new System.Collections.Generic.IEnumerator<Class2> GetEnumerator()
{
yield return new Class2();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
然后是代码
var l = new List2();
var first = l.First();
不会编译,但会报错
'List2' does not contain a definition for 'First' and no extension method 'First' accepting a first argument of type 'List2' could be found (are you missing a using directive or an assembly reference?)
如果 List2 不是从 List1 派生的,那么它可以编译,这证明 List2 确实有一个有效的扩展方法。
这只是一个误导性错误的情况,问题是它有两个扩展方法,不知道该选择哪个?
如果是这样,为什么它不能像编译器使用方法重载解析一样告诉 Class2 是更具体的版本?
最佳答案
问题是 List2
同时实现 IEnumerable<Class1>
和 IEnumerable<Class2>
,所以编译器不知道 Enumerable.First<Class1>
中的哪一个或 Enumerable.First<Class2>
打电话。实际上,没有最好的 T
编译器可以找到调用 Enumerable.First<T>(l)
, 所以它不计算任何通用 Enumerable.First<T>
作为一种合格的方法。因此,它现在只查找名为 First
的非泛型方法。使用一个参数 l
可以隐式转换为,但找不到任何内容。
你可以明确地说
var first = l.First<Class1>();
或
var first = l.First<Class2>();
然后你就没事了。
关于c# - 派生类上没有扩展方法 'First',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16818927/