【问题标题】:Why can't static method in non-static class be an extension method? [duplicate]为什么非静态类中的静态方法不能是扩展方法? [复制]
【发布时间】:2011-11-16 08:55:38
【问题描述】:

可能重复:
extension method requires class to be static

在 .NET 中:

为什么非静态类中的静态方法不能是扩展方法?

【问题讨论】:

  • 我想这与方法的连接方式有关。扩展方法实际上从未附加到它们的目标类。这就是编译器/IDE 的魔力。他们属于自己的,独立的班级。为此,每次调用目标方法时,框架都需要创建“扩展”类的新实例。我个人不知道他们是如何探索扩展方法的,但我可以看到这会在哪里出现问题。留下评论,希望有人对此有明确的答案......
  • 发现这是一个寻找 Eric Lippert 报价的骗子 =)
  • 因为微软是这么说的。也许其他原因围绕着将某人的图书馆变成反对他们的问题,因为它变成了变异的代码僵尸。对于提供 3rd 方解决方案(PDF 生成等)的公司来说,你“想要”的东西是有风险的,而鬼鬼祟祟的开发人员可以做他们不应该做的事情。扩展方法是扩展类,而不是让你完全控制它的内部。
  • @Pete 静态函数不需要非静态类的实例存在。
  • TL;DR 没有技术原因。这是一个设计决定。

标签: c# .net static extension-methods


【解决方案1】:

Eric Lippert 可能会在这个问题上给出一个非常好的答案,但它的要点可能是:

我们认为,如果我们限制您必须寻找扩展方法的位置数量,那么程序员和编译器都会更容易。

此政策倾向于强制用户将所有扩展方法放入为此目的指定的几个特定类中。

【讨论】:

  • 对我来说似乎是一个任意的限制。扩展实例方法是语法糖,而不是静态方法不能被甜化一点的原因。
  • @Hemal:我认为扩展方法只需要一点任意限制。它可以防止句法糖像句法可卡因一样被使用。
  • @Hemal:好处是实例级扩展方法更加自然和方便,它们是使LINQ工作所必需的。使 LINQ 工作不需要静态扩展方法。这是一个重复的问题,请阅读原文和 Eric Lippert 的回复。
  • @Ed 感谢您向我指出这一点。我现在明白了,添加了扩展方法以使 LINQ 工作。 LINQ 不需要静态扩展方法,因此没有添加它们。如果实例和静态方法都可以定义为扩展,我的工作——将一些客户端代码移植到新版本的 API——会更容易,所以我对没有静态扩展方法感到遗憾。有意义吗?
  • 你提出的“要点”是一个很好的总结,而且正如 Ed 指出的那样,几乎所有不需要 LINQ 工作的特性都被删掉了。
【解决方案2】:

静态类需要有扩展方法是有道理的。第一个原因是静态类是无状态的......即您不必实例化该类。 ...但这只是我的直觉。否则对我来说没有意义。

我也认为,强制扩展方法驻留在公共/内部静态类中会降低使用它们的成本。

【讨论】:

  • 您不需要实例来调用静态方法。
  • @Jason - 我没有说你需要一个实例来调用静态方法。在实例类中使用 public static void ExtMethod(this whatever) 是没有意义的......
  • 为什么没有意义?我在看着你String.IsNullOrEmpty
  • IMO,如果扩展方法从一开始就是 .Net 的一部分,许多类和原始类型看起来会大不相同:myStrVar.IsNullOrEmpty()
  • @IAbstract:实际上,通过允许将非虚拟方法显式声明为“null-accepting”,可以更干净地处理这个问题。顺便说一句,让我对扩展方法感到恼火的一件事是,类或接口无法在自身上声明扩展方法,并且让这些方法遵守与类或接口相同的范围规则。
【解决方案3】:

因为,嗯,就是这样。

我的猜测是,允许使用静态扩展方法会使语言复杂化(每个功能都会增加一种或另一种类型的复杂性),而好处几乎为零。例如,如果您在 String 上定义静态方法,那么当您可以使用相同的静态方法简单地定义自己的类时,这样做有什么好处?

实例级扩展方法很有用,因为它们适用于类型实例的当前状态。静态方法没有上下文,因此除了逻辑分组之外,它不会为在其他地方定义的静态方法提供任何实用程序(即,定义一个 String.IsNullOrFullOfSomeChar(char c) 在逻辑上属于 String 类在逻辑上是有意义的,但除此之外还有没有优势。是的,这将是一个可怕的方法,只是一个例子)。

扩展方法是 LINQ 的结果。实施它们是为了让 LINQ 以设计人员想要的方式工作。静态扩展不是必需的,因此,它们没有实现。

【讨论】:

  • NB 在您开始阅读之前,这回答了wrong question - 请参阅下面的 StriplingWarrior 的回答以获得有根据的猜测
【解决方案4】:

在编译时,每当您为扩展方法使用实例语法糖时,这都会转换为对静态方法(定义扩展)的调用,并通过您的实例。

除了漂亮的语法之外,实现静态方法并将实例作为参数传递并没有什么不同。这正是发生的事情。您不能对静态类执行此操作,因为您不能将静态类作为参数传递给方法。

【讨论】:

  • 这与提出的问题无关。您正在争论扩展静态类。
  • 实际上我在回答为什么扩展方法不能与静态类一起使用的问题。答案是因为扩展方法被编译成静态方法,无法接收到静态类的引用。
猜你喜欢
  • 2011-01-01
  • 2011-03-02
  • 1970-01-01
  • 2011-12-11
  • 1970-01-01
  • 2011-01-24
  • 2011-12-08
  • 2011-07-11
  • 2011-05-29
相关资源
最近更新 更多