[英]Why can you not invoke extension methods directly?
有人可以向我解释为什么在下面第三次调用 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");
}
}
可以像其他静态方法一样调用扩展方法。
将其更改为A_Ext.DoSomething(this)
。
如果您要问为什么不在this
上隐式调用this
,答案是规范就是这样编写的。 我认为原因是在没有限定符的情况下调用它会产生误导。
因为DoSomething
需要一个参数。
DoSomething(a)
是合法的。
编辑
我在这里读错了这个问题。
由于您将其称为普通静态方法,而不是扩展方法,因此您需要使用类名进行前缀。
所以A_Ext.DoSomething(a);
将工作。
如果您像普通静态方法一样调用它,则所有相同的规则都适用。
您的第二个变体有效,因为 B 继承了 A,因此您最终仍将其作为扩展方法调用,但第三个变体没有。
遗憾的第一个版本以上不工作。 我会留下它以保持评论的相关性。
DoSomething
需要一个A
的实例来做任何事情,如果没有限定符,编译器就看不到你需要调用哪个DoSomething
。 它不知道为您的方法检查A_Ext
,除非您使用this
限定它。
扩展方法仍然是静态方法,不是真正的实例调用。 为了使其工作,您需要使用实例方法语法的特定上下文(来自扩展方法(C# 编程指南) )
在您的代码中,您使用实例方法语法调用扩展方法。 但是,编译器生成的中间语言 (IL) 会将您的代码转换为对静态方法的调用。 因此,并没有真正违反封装原则。 事实上,扩展方法不能访问它们正在扩展的类型中的私有变量。
因此,虽然通常情况下,两种语法都可以使用,但第二种语法没有明确的上下文,并且生成的 IL 似乎无法隐式获取上下文。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.