public class StoreController : Controller
{
public string Index()
{
// implicitly specified instance does not work
//return GetMemberName();
// must specify this explicitly
return this.GetMemberName();
}
}
public static class Utilities
{
public static string GetMemberName(this Controller caller,
[CallerMemberName] string memberName = "")
{
return caller.GetType().FullName + "." + memberName;
}
}
为什么在从扩展类的方法中调用扩展方法时,我们必须显式指定this
?
在我的心理模型中,我们通常可以省略this
,例如我们初始化字段时。例如。
答案 0 :(得分:3)
扩展方法在技术上不是附加到您的类的方法。
yourClass.ExtensionMethod()
与yourClass.ClassMethod()
不同。
基本上,你正在做的是方便地做到这一点:
ExtensionMethod(YourClass yourClass) {
//do something
return yourClass;
}
这是我对扩展方法的理解。对于无法更改的类调用方法,这是一种方便的方法。所以,这就是为什么你不能在没有this.
的情况下调用它。它不是类方法。
答案 1 :(得分:2)
扩展方法只是一种调用静态方法的语法糖。这段代码return this.GetMemberName();
实际上转换为对Utilities.GetMemberName(this);
如您所见,您必须将this
发送到静态方法,这就是您需要this
个关键字的原因。
答案 2 :(得分:1)
没有参加设计委员会的决定,很难说这就是为什么。
在本文中,我使用与特定对象实例相关联的函数意义上的方法或实例方法,并且我在数学意义上使用函数。函数接收许多参数并创建结果(可能无效)
如果我们不考虑更复杂的虚方法,因为要调用的实际函数是运行时确定的,那么任何和所有方法调用都是语法糖。如果我们在下面定义了两种方法
internal static class Extensions {
public static string FooEx(this MyClass self){
return self.ToString();
}
}
internal class MyClass {
public string Bar(){
var s1 = Foo();
var s2 = this.FooEx();
}
private string Foo(){
return ToString();
}
}
然后两者都将被转换为函数调用,其中两个个案中的第一个(也是唯一的)参数将是this
标识的对象。如果您对此有疑问,那么请查看为实例方法调用而生成的IL,您会注意到与代码中的声明相比有一个额外的参数。此参数是this
引用,始终作为实例方法的第一个参数传递。
因此,在实例方法的情况下,编译器仍然需要确定要传递哪个对象作为函数的第一个参数。如果你在没有this
的情况下调用扩展方法,那就完全一样,这也意味着这不是你必须使用this
的真正原因在扩展方法面前。
在Marvin的编译器中,构建在Mono编译器之上的编译器我必须做与C#类似的技巧和扩展方法,并且想知道为什么规范需要this
编译器强制您在扩展方法之前使用this
的真正原因是规范是这样说的。这个决定背后的原因是什么需要像@EricLippert这样的人注意,他们可能在那里决定了这个要求