在C#中的静态方法的形式参数中使用"this"关键字

kpo*_*zin 269 c# parameters this

我遇到过几个C#代码实例,如下所示:

public static int Foo(this MyClass arg)
Run Code Online (Sandbox Code Playgroud)

this在这种情况下,我无法找到关键字含义的解释.任何见解?

Pre*_*gha 256

这是一种扩展方法.请看这里的解释.

扩展方法允许开发人员向现有CLR类型的公共协定添加新方法,而无需对其进行子类化或重新编译原始类型.扩展方法有助于将当今动态语言中流行的"duck typing"支持的灵活性与强类型语言的性能和编译时验证相结合.

扩展方法支持各种有用的场景,并有助于实现真正强大的LINQ查询框架....

这意味着你可以打电话

MyClass myClass = new MyClass();
int i = myClass.Foo();
Run Code Online (Sandbox Code Playgroud)

而不是

MyClass myClass = new MyClass();
int i = Foo(myClass);
Run Code Online (Sandbox Code Playgroud)

这允许构建如下所述的流畅界面.

  • 抱歉,有点讽刺-这些天很多语法似乎可以解决我什至不知道是问题的问题。可读性应该是非常重要的。 (5认同)
  • 说实话@Gerry,听起来有点像你处于经典的[Blub Paradox](https://wiki.c2.com/?BlubParadox)中。如今,很多语法都可以解决您没有遇到的问题,因为您不知道有更好的方法,或者您没有执行该语法所擅长的任务。大多数关于“_这是一个寻找问题的解决方案_”的评论实际上是“_我不知道该功能如何工作,所以它一定是无用的_”的例子。 (3认同)

Jam*_*man 49

Scott Gu的引用博客文章很好地解释了这一点.

对我来说,问题的答案在该帖子的以下声明中:

注意上面的静态方法如何在string类型的第一个参数参数之前有一个"this"关键字.这告诉编译器应该将这个特定的扩展方法添加到"string"类型的对象中.在IsValidEmailAddress()方法实现中,我可以访问调用该方法的实际字符串实例的所有公共属性/方法/事件,并根据它是否是有效的电子邮件返回true/false.

  • 这应该是公认的答案.这是唯一能够解释方法签名中`this`关键字的实际用途的答案.另一个答案只是无益地说"这是一种扩展方法".在阅读这个答案之前,我从未完全理解扩展方法如何"附加"它们延伸的类型.谢谢! (8认同)

Dea*_*n P 15

如果你可以整齐地弹出一个List<>,即不仅删除第一个元素,还返回它,不是很方便吗?

List<int> myList = new List<int>(1, 2, 3, 4, 5);
Run Code Online (Sandbox Code Playgroud)

没有扩展方法:

public static class ContainerHelper
{
    public static T PopList<T>(List<T> list)
    {
        T currentFirst = list[0];
        list.RemoveAt(0);
        return currentFirst;
    }
}
Run Code Online (Sandbox Code Playgroud)

调用这个方法:

int poppedItem = ContainerHelper.PopList(myList);
Run Code Online (Sandbox Code Playgroud)

使用扩展方法:

public static class ContainerHelper
{
    public static T PopList<T>(this List<T> list)//Note the addition of 'this'
    {
        T currentFirst = list[0];
        list.RemoveAt(0);
        return currentFirst;
    }
}
Run Code Online (Sandbox Code Playgroud)

调用这个方法:

int poppedItem = myList.PopList();
Run Code Online (Sandbox Code Playgroud)


Oli*_*bes 13

除了Preet Sangha的解释:
Intellisense用蓝色箭头显示扩展方法(例如在"Aggregate <>"前面):

在此输入图像描述

你需要一个

using the.namespace.of.the.static.class.with.the.extension.methods;
Run Code Online (Sandbox Code Playgroud)

如果扩展方法与使用它们的代码位于不同的命名空间中,则显示和可用的扩展方法.


JP *_*oto 8

它们是扩展方法.欢迎来到一个全新的流畅世界.:)


jpo*_*poh 5

前几天我自己才了解到这一点:this 关键字定义该方法是执行该方法的类的扩展。因此,对于您的示例,MyClass 将有一个名为 Foo 的新扩展方法(它不接受任何参数并返回 int;它可以与任何其他公共方法一样使用)。