为什么扩展方法需要“静态”和“这个”,它们的内存如何分配?

时间:2011-04-20 12:10:40

标签: c# .net extension-methods

关于扩展方法的一些问题:

  1. 为什么扩展方法是静态的?

  2. 为什么需要在静态类中声明它们?

  3. 此关键字在扩展方法的参数列表中表示什么?由于它是一个静态类,“this”关键字如何在此上下文中起作用?

  4. 这些类型的方法如何进行内存分配?

5 个答案:

答案 0 :(得分:8)

静态和非静态方法之间的唯一区别是非静态方法接收隐式参数 - this。扩展方法不会在声明方法的对象的上下文中调用,因此无法将this引用传递给它们,因此它们必须是静态的。

您无法在扩展方法中使用关键字this,我希望这可以回答您的第三个问题。参数列表中的this关键字仅用于指示此方法扩展的类型。

关于内存分配的问题是什么?扩展方法就像任何其他静态方法一样,只有调用语法不同。

答案 1 :(得分:3)

  

为什么扩展方法是静态的?

因为您无法修改类以添加实例方法。将这些方法调用得更好,这就是所有的语法糖,仅此而已。

  

为什么需要在静态类中声明它们?

因为我们不打算创建类的实例。这是一个设计决定。为什么复杂的事情比如让一些类的实例附加到它们的扩展方法甚至可能无法使用呢?

  

此关键字在扩展方法的参数列表中表示什么?因为它是一个静态类,“this”关键字在这种情况下如何工作?

这是一种静态方法。 this在这方面没有任何意义。签名中的this只是表示正在声明扩展方法的一种方式。

  

这些类型的方法如何进行内存分配?

对此感到困惑。它们都是静态类的静态方法。它们像任何其他(静态)方法一样被“分配”,只有该类型代码的一个副本。

答案 2 :(得分:1)

  1. 因为没有实例可以调用它们。

  2. 我认为如果它是在非静态类中声明的话,它会限制可能的错误数。

  3. 它说它的扩展方法。编译器会看到这一点并允许在声明为此类型的类型上使用它,而不是静态方法。

  4. 扩展方法调用只是语法糖。此调用将转换为IL中的普通静态方法调用。

答案 3 :(得分:1)

1,2和4的答案几乎相同。扩展方法只是带有一些特殊语法糖的静态方法。这样:

public static void DoIt(this string str) {
    // ..
}

"test".DoIt();

实际上与IL相同:

public static void DoIt(string str) {
    // ..
}

DoIt("test");

前一种方法使得提供IntelliSense支持变得更加容易。需要静态的类的限制可能只是一个设计决策,或者可能与性能有关。

#3的答案就是语言设计者选择的语法。 C#开发人员习惯this引用实例对象。他们本可以称之为blah,但它不会像实例对象那样明显。

在扩展方法中使用this关键字也会告诉C#编译器使用ExtensionAttribute标记它。程序集的使用者可以使用此属性来查找扩展方法。

答案 4 :(得分:0)

这就是它们的定义方式 - 在第一个参数之前使用此关键字,这是您调用方法的对象的实例。为什么ToString()调用ToString()?为什么静态用于静态?草为什么是绿色的?我想决定将这个放在第一个参数前的权力,而不是想出一个新的关键字“extension”放在方法名称前面。

编译器生成的IL将您的代码转换为对静态方法的调用,即使语法看起来像是对实例方法的调用。但它不是 - 它是静态的,无法访问对象的私有成员。