为什么在实现接口的类中调用接口扩展方法时需要使用this限定符?

3

给定接口

public interface IHaveError
{
    string ErrorMessage { get; set; }
}

扩展

public static class HaveErrorExtensions
{
    public static void SetErrorMessage(this IHaveError target, string message)
    {
        target.ErrorMessage = message;
    }
}

public class HaveError : IHaveError
{
    public string ErrorMessage { get; set; }

    public void DoSomething()
    {
        this.SetErrorMessage(message);
    }
}

为什么在调用扩展方法时需要使用this.?如果不加它,名称就无法解析。
3个回答

4
这就是C#语言规范中扩展方法的工作原理。如果你阅读7.6.5.2节"扩展方法调用",基本上它说你必须有以下形式之一的方法调用:
expr . identifier ( )
expr . identifier ( args )
expr . identifier < typeargs > ( )
expr . identifier < typeargs > ( args )

如果你注意到了,expr是扩展方法搜索的必选项。

在这种情况下,this.变成了上面的expr.,因此上面的代码可以被翻译为静态方法调用,其中该方法被定义为一种扩展方法:

C . indentifier ( expr , args )

在你的情况下,为了让编译器“找到”(甚至是搜索)方法调用,你需要指定某些“表达式”类型。明确的this。有资格。它会导致编译器采取这个:
this.SetErrorMessage(message);

并搜索与该类型配合使用的匹配扩展方法,将其翻译为:

HaveErrorExtensions.SetErrorMessage(this, message);

4

扩展方法其实是一些带有语法糖(非常美味的语法糖)的静态方法,由编译器处理。调用该方法的对象引用实际上是该方法的第一个参数。

编译器需要知道你指的实例是什么,它不能猜测。


3

因为this指的是你当前正在使用的对象。如果没有this,编译器就不知道应该将扩展方法应用在哪个对象上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接