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

Posted

技术标签:

【中文标题】在 C# 中静态方法的形式参数中使用“this”关键字【英文标题】:Use of "this" keyword in formal parameters for static methods in C# 【发布时间】:2010-10-25 05:01:54 【问题描述】:

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

public static int Foo(this MyClass arg)

在这种情况下,我无法找到对 this 关键字含义的解释。有什么见解吗?

【问题讨论】:

除了接受的答案外,对于 C# 扩展方法,必须查看官方 MSDN documentation。 扩展方法很方便,但我们在创建/使用它们时必须小心——它们可能会损坏!引用official MSDN documentation 中的一般准则:“一般来说,我们建议您谨慎地实现扩展方法,并且仅在必须时才实现。......当使用扩展方法来扩展您无法更改源代码的类型时,您冒着改变类型实现会导致扩展方法中断的风险。” 这是否意味着this 是可能的?因为这就是我要找的。​​span> 【参考方案1】:

这是一种扩展方法。在这里查看explanation。

扩展方法允许开发人员向公众添加新方法 现有 CLR 类型的合约,无需对其进行子类化或 重新编译原始类型。扩展方法有助于融合 在动态语言中流行的“鸭子打字”支持的灵活性 今天的性能和编译时验证 强类型语言。

扩展方法支持各种有用的场景,并帮助 可能是真正强大的 LINQ 查询框架...。

表示可以调用

MyClass myClass = new MyClass();
int i = myClass.Foo();

而不是

MyClass myClass = new MyClass();
int i = Foo(myClass);

这允许构造fluent interfaces,如下所述。

【讨论】:

子分类很难 @Gerry - 你是什么意思? 抱歉,有点讽刺——这些天很多语法似乎解决了我什至不知道是问题的问题。可读性应该是一个非常高的优先级。 老实说@Gerry,这听起来像是你在经典的Blub Paradox。现在很多语法解决了你没有遇到的问题,因为你不知道有更好的方法,或者你没有做这种语法很棒的任务。大多数关于'这是一个寻找问题的解决方案'的cmets实际上是'我不知道该功能是如何工作的,所以它一定没用'的一个例子.【参考方案2】:

Scott Gu's quoted blog post 解释得很好。

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

注意上面的静态方法有一个 第一个之前的“this”关键字 字符串类型的参数参数。 这告诉编译器这 特定的扩展方法应该是 添加到“字符串”类型的对象。 在 IsValidEmailAddress() 内 方法实现我可以然后 访问所有公众 的属性/方法/事件 该方法的实际字符串实例 被召唤,并返回 真/假取决于它是否 是否是有效的电子邮件。

【讨论】:

这应该是公认的答案。这是唯一真正解释方法签名中 this 关键字的实际用途的答案。其他答案只是无济于事地说“这是一种扩展方法”。在阅读此答案之前,我从未完全理解扩展方法如何“附加”到它们扩展的类型。谢谢!【参考方案3】:

In addition to Preet Sangha's explanation: Intellisense 用蓝色箭头显示扩展方法(例如在“Aggregate”前面):

你需要一个

using the.namespace.of.the.static.class.with.the.extension.methods;

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

【讨论】:

【参考方案4】:

他们是extension methods。欢迎来到全新的fluent world。 :)

【讨论】:

【参考方案5】:

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

【讨论】:

【参考方案6】:

如果你能巧妙地弹出一个List,那不是很方便吗,即不仅删除第一个元素,还返回它?

List<int> myList = new List<int>(1, 2, 3, 4, 5);

没有扩展方法:

public static class ContainerHelper

    public static T PopList<T>(List<T> list)
    
        T currentFirst = list[0];
        list.RemoveAt(0);
        return currentFirst;
    

调用这个方法:

int poppedItem = ContainerHelper.PopList(myList);

使用扩展方法:

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;
    

调用这个方法:

int poppedItem = myList.PopList();

【讨论】:

【参考方案7】:

“this”扩展了参数列表中的下一个类

所以在“this”下面的方法签名中扩展了“String”。行作为方法的普通参数传递给函数。 public static string[] SplitCsvLine(这个字符串行)

在上面的例子中,“this”类扩展了内置的“String”类。

【讨论】:

以上是关于在 C# 中静态方法的形式参数中使用“this”关键字的主要内容,如果未能解决你的问题,请参考以下文章

C#原始类型扩展方法—this参数修饰符

C#的扩展方法解析

C# this扩展方法

C# 语法 ( 扩展方法 )

C#在静态方法中检索类名

如何实现我另一个窗口关闭时,刷新这个窗口(C#中问题)