有人可以向我解释为什么在下面的第三次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");
}
}
答案 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无法隐式获取上下文。