【问题标题】:C# Extension methods in .NET 2.0.NET 2.0 中的 C# 扩展方法
【发布时间】:2010-02-17 00:05:11
【问题描述】:

我找到了几个使扩展方法在 .NET2.0 中工作的方法的链接(The mothDiscord & RhymeStack Overflow)。我也从一位同事那里含糊地听说这会导致图书馆出现一些问题或其他什么?是这样吗?并且所有 3 使用不同的方法:

The moth:

namespace System.Runtime.CompilerServices
{
  public class ExtensionAttribute : Attribute { }
}

Discord and Rhyme

namespace System.Runtime.CompilerServices
{
  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
  public class ExtensionAttribute : Attribute {}
}

Stack Overflow

namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class
         | AttributeTargets.Method)]
    public sealed class ExtensionAttribute : Attribute {}
}

这些方法有什么区别,你会推荐哪一种?

【问题讨论】:

标签: c# .net


【解决方案1】:

最终不会有太大的不同;您可能会争辩说,与运行时匹配的那个是首选,但 理想 的答案是切换到 .NET 3.5(否则在以后它可能会与范围内相同属性的不同版本混淆等)。

[AttributeUsage] 将防止它被附加到它不会做任何事情的东西上 - 但它不会做任何事情它自己无论如何......

根据类型查看元数据,确切的属性使用似乎最像 stackoverflow 变体 - 但最终这并不是非常重要 - namenamespace 就是全部这很重要(并且它继承自 Attribute)。

【讨论】:

【解决方案2】:

区别很简单:

在您的第一个示例中,您可以将属性放在任何位置。在第二个例子中,你只能将它应用到一个方法上,同一个方法不能超过一个,并且一个被重写的方法的继承类将不会继承该属性。在第三个示例中,您可以将其应用于方法、类或程序集。

如果你尝试在任何其他地方应用它,你会得到一个编译器错误。

第二个似乎最有意义。

【讨论】:

    【解决方案3】:

    我会推荐 Discord and Rhyme,因为它为应该如何应用属性提供了有意义的约束。

    1. 只能应用于方法
    2. 您只能应用一次
    3. 属性不能被继承

    【讨论】:

      【解决方案4】:

      就个人而言,我建议避免所有这三个。每个选项都通过执行“技巧”来完成这项工作 - 我不会依赖它来生成生产代码。

      如果要使用扩展方法,请升级到 C# 3.0。否则,只需坚持使用非扩展方法语法调用该方法。

      您总是可以像这样调用扩展方法:

      public static class Utility {
          public static string Extension(this string original) { ... }
      
      // call with:
      var newString = myString.Extension();
      

      并直接调用:

      string newString = Utility.Extension(myString);
      

      这将更符合 C#/.NET 2 语法,并且是我的建议。

      【讨论】:

      • this有什么作用?
      • 这会导致 System.Runtimes.CompilerServices.Extension 属性被放置在 C# 3 中的方法调用上。这就是使“扩展”方法作为扩展方法而不是标准静态方法工作的原因。
      • 这有什么不同?这是否允许我们访问方法中的私有范围?
      • @Casebash:不。从功能上讲,它是相同的。它只允许 C# 3 将其视为扩展方法,因此您可以编写“myString.Extension()”而不是“Utility.Extension(myString)” - 这就是我说的原因,如果你在 C# 2 中,坚持到 C# 2,因为它没有提供任何优势(除了方便)。
      • 你说你不会依赖它来生产代码。怎么会破?
      【解决方案5】:

      SO 版本是准确的版本,为了准确起见,您应该使用它。

      Fwiw,AttributeTarget.Method 说明符非常清晰。类和程序集更少。 C# 和 VB.NET 编译器都会在包含扩展方法的静态类/模块上发出属性。并在包含类/模块的程序集上。他们为什么这样做不太清楚,不需要正确编译它们。我猜这是一个优化工作,帮助编译器和 IntelliSense 发现何时应该考虑扩展方法。

      获取应用到程序集的属性实际上是一个问题。当您将代码编译为 .netmodules 时,这将无法正常工作。但这是一个非常模糊的问题。

      【讨论】:

      • 什么是网络模块,当我尝试编译到它时会发生什么?
      • 也许是另一个问题的好话题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-24
      • 2021-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多