【问题标题】:Extension methods in C#: why does this work?C# 中的扩展方法:为什么会这样?
【发布时间】:2010-08-20 22:16:37
【问题描述】:

我有点困惑为什么这不会出错。我在一些过时的遗留软件的深处发现了这段代码,并惊讶地发现它可以工作。

public static string CleanFileName(this string fileName)
{
  return CleanFileName(fileName, 64);
}

public static string CleanFileName(this string fileName, int maxLength)
{
  //some logic
}

我对扩展方法的经验是这样称呼它:

fileName.CleanFileName(64);

这仅仅是因为它也是一个静态方法吗?这是常见的做法,只是我还没有看到的东西,还是我应该用火杀死的过时的遗留代码?

【问题讨论】:

  • 为什么你认为这不起作用? msdn.microsoft.com/en-us/library/bb383977.aspx 明确指出 Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type

标签: c# static extension-methods this legacy-code


【解决方案1】:

扩展方法总是可以选择调用,就好像“this”修饰符不存在一样(也称为普通静态方法)。这样做的可读性较差,但在语法上是有效的。

另一个答案具有误导性,因为“它之所以有效,是因为方法调用是在与其重载相同的类型中进行的。”暗示了一些关于扩展方法的东西。无论您碰巧在哪个类中,您都可以将扩展方法作为普通静态方法调用。但是通过下面的 cmets,听起来混淆是类是否需要限定。在这种情况下,Nathan 是正确的,可以省略类名的原因是因为调用发生在与重载相同的类中。

【讨论】:

  • 我认为另一个答案是“明显错误”的说法是不正确的。在一个类型中,您可以调用该类型的静态方法,而无需在方法调用前加上声明类型。因此,在同一类型中看到来自另一个扩展方法的调用而没有声明类型前缀,就像任何其他不是“扩展”的静态声明一样。
  • 是的,但要点是与你是否“属于同一类型”无关。您可以使用 any 类型的语法。
  • 您不能调用CleanFileName(fileName, 64);,因为它是在扩展类之外输入的。在扩展类之外,该方法调用必须以声明类型为前缀,例如 string.CleanFileName(fileName, 64); 或在字符串的实例上,例如 mystring.CleanFileName(64); 我认为这是 OP 提出原始问题的意图。
  • Kirk 的观点也适用于它就像任何常规静态方法一样,但我相信 OP 对为什么可以在没有类名或实例前缀的情况下调用它感到困惑。
  • 扩展方法非常酷,但是它们的实现方式却导致了很多混乱。有点可惜。
【解决方案2】:

之所以有效,是因为对CleanFileName(string, int) 的调用是从与CleanFileName(string) 相同的类型中进行的,这允许以标准方法语法而不是扩展方法语法进行调用。因此,扩展方法前面不需要字符串实例前缀。

从语义上讲,static string Foo(this string foo, int bar) { }可以以Foo(string, int)string.Foo(int)的形式调用。

【讨论】:

  • 我没有投反对票,但答案与您是否从“相同类型的内部”调用它无关。
  • 我不明白你的意思?这正是答案的意义所在。
  • 投反对票是因为答案仅仅是第一句话,它不完整以至于不正确。第二段对其进行了改进,但简单的答案是可以使用完整的 Class.Method 语法或通过扩展简写来调用扩展方法,无论是在类内部还是外部都与它无关。
  • 扩展方法是通过传入所有参数(包括第一个参数)以普通方式调用静态方法的语法糖。 (实际上对扩展方法的调用总是编译成普通的静态方法调用)
  • @Nathan,这句话是错误的:“它之所以有效,是因为方法调用是从与其重载相同的类型中进行的。”
猜你喜欢
  • 2011-01-25
  • 2010-12-26
  • 2012-02-01
  • 1970-01-01
  • 2013-07-26
  • 1970-01-01
  • 2016-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多