c# - 派生类上没有扩展方法 'First'

标签 c# generics extension-methods

给定(非常简单的)代码。

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/

相关文章:

c# - Func<TResult> 方法参数的首选命名约定是什么?

c# - 通用类型的 ASP.NET MVC 模型绑定(bind)器

java - 将类型参数传递给接口(interface)方法

swift - swift 泛型函数中的类型可以由返回值决定吗?

c# - 何时使用扩展方法?

c# - MVC Unobtrusive validation data-val-* markup attributes not being generated

c# - 当xml元素为空时,XmlSerializer抛出异常

c# - 为什么在使用静态导入时不能将扩展方法作为静态方法调用?

c# - 如何在枚举上创建扩展方法 (c#)

c# - 正则表达式获取特定属性的值?