在扩展方法中使用它们所扩展的类

5

考虑以下这个类:

public class Thing {

    public string Color { get; set; }

    public bool IsBlue() {
        return this.Color == "Blue";   // redundant "this"
    }

}

我可以省略关键字this,因为ColorThing的属性,并且我正在Thing内部编码。如果现在创建一个扩展方法:
public static class ThingExtensions {

    public static bool TestForBlue(this Thing t) {
        return t.Color == "Blue";
    }

}

现在我可以将我的IsBlue方法更改为以下内容:

public class Thing {

    public string Color { get; set; }

    public bool IsBlue() {
        return this.TestForBlue();   // "this" is now required
    }
}

然而,我现在必须包括this关键字。

当引用属性和方法时,我可以省略this,那么我为什么不能这样做呢...?

public bool IsBlue() {
    return TestForBlue();
}

1
扩展方法实际上并不扩展类型。它们只是通过 IDE 和编译器的技巧来实现这一点。 - Oded
顺便说一句,我可以轻松地输入 this,只是我对编码的整洁性有强迫症,这个关键字让我很烦恼!!! - BG100
Habib所回答的问题完美解决了这个问题。 - jeroenh
该死...我确实试图先搜索重复问题...但是什么都没找到!! 显然我没有认真找。 - BG100
它也可以像普通的静态方法一样被调用ThingExtensions.TestForBlue(this) - Olivier Jacot-Descombes
2个回答

14
当引用属性和方法时,我可以省略它,那为什么我不能这样做呢...?这基本上是调用扩展方法的一部分。C#规范第7.6.5.2节(扩展方法调用)中开始说:
在以下形式之一的方法调用(7.5.5.1)中
expr.identifier() expr.identifier(args) expr.identifier() expr.identifier(args)
如果正常处理调用时找不到适用的方法,则尝试将构造视为扩展方法调用。
没有“this”,您的调用就不是那种形式,因此规范中的该部分不适用。
当然,这并不是为什么设计该功能的理由 - 这是关于编译器行为正确性的证明。

Section 7.6.5.2 指的是哪个文档?谷歌似乎不知道... - BG100
1
@BG100 C# 5.0语言规范。 - Servy
@BG100:规范可在http://www.microsoft.com/en-us/download/details.aspx?id=7029免费下载。 - Brian

0

由于需要调用哪个扩展方法类型,因为扩展被定义为Thing,所以对象需要调用自身和为其定义的静态方法


1
C#规范本可以轻松检查调用类(和基类),并为我们检查。但他们没有这样做。我只能假设在某个时候他们会为我们添加这个功能。 - user441521

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