为什么不能直接调用扩展方法?

时间:2010-10-11 12:29:51

标签: c# extension-methods

有人可以向我解释为什么在下面的第三次DoSomething调用无效? (错误消息是“名称'DoSomething'在当前上下文中不存在”)

public class A { }
public class B : A
{
    public void WhyNotDirect()
    {
        var a = new A();
        a.DoSomething();  // OK
        this.DoSomething();  // OK
        DoSomething(); // ?? Why Not
    }
}
public static class A_Ext
{
    public static void DoSomething(this A a)
    {
        Console.WriteLine("OK");
    }
}

4 个答案:

答案 0 :(得分:5)

可以像其他静态方法一样调用扩展方法。

将其更改为A_Ext.DoSomething(this)

如果你问为什么没有在this上隐式调用它,那么答案就是规范的编写方式。我认为原因是在没有限定符的情况下调用它会产生误导。

答案 1 :(得分:3)

因为DoSomething需要参数。

DoSomething(a)是合法的。

修改

我在这里读到的问题有点不对。

由于您将其称为常规静态方法,而不是扩展方法,因此您需要使用类名称进行预处理。

所以A_Ext.DoSomething(a);会有用。

如果您将其称为普通静态方法,则适用所有相同的规则。

你的第二种变体是有效的,因为B inhetits A,因此你仍然最终称它为扩展方法,但第三种不是。

抱歉上面的第一个版本工作。我会留下来保持评论的相关性。

答案 2 :(得分:2)

DoSomething需要A的实例来执行任何操作,如果没有限定符,编译器将无法查看您需要调用的DoSomething。除非您使用A_Ext对其进行限定,否则无法检查this您的方法。

答案 3 :(得分:2)

扩展方法仍然是静态方法,而不是真正的实例调用。为了使其工作,您需要使用实例方法语法(来自Extension Methods (C# Programming Guide)

的特定上下文
  

在您的代码中,您可以调用扩展程序   方法与实例方法语法。   但是,中间语言   (IL)由编译器生成   将您的代码转换为通话   静态方法。因此,   封装原则不是   真的被侵犯了。事实上,   扩展方法无法访问   它们所属的私有变量   延伸。

因此,通常情况下,两种语法都可以工作,第二种语法没有显式上下文,看起来生成的IL无法隐式获取上下文。