【问题标题】:When do you use extension methods, ext. methods vs. inheritance?你什么时候使用扩展方法,分机。方法与继承?
【发布时间】:2009-04-24 19:55:25
【问题描述】:

我们开始使用 C# (.NET 3.0),我想知道你们是如何使用扩展方法的?你什么时候使用它们?

另外,如果您还列出使用它们的所有黑暗先决条件,我将不胜感激。

【问题讨论】:

标签: c# .net


【解决方案1】:

使用扩展方法的次数:

  • 当您不控制要扩展的类型时
  • 您不想强制实现者提供可以使用现有方法完成的代码

以第二点为例;您可能在IList<T> 上有一个扩展方法(例如Sort),它可以完全使用现有的IList<T> 成员编写……那么为什么要强迫其他人写任何东西呢?这是 LINQ 的基础块,允许 Microsoft 在不破坏任何东西的情况下提供更多更多功能。

使用扩展方法的时间:

  • 当多态性很关键时;您不能保证您的代码将是使用扩展方法执行的版本,因为直接在类型上的方法优先
  • 当您需要访问私有/受保护成员时

【讨论】:

  • 我不理解 not 使用扩展方法的第一点。
  • @student,与此有关(在另一个答案中提到):“不会调用与实例方法具有相同名称和签名的扩展方法”。如果某个继承类实现了与扩展方法完全相同的签名,则将调用类方法而不是扩展。
  • 扩展方法和普通静态方法在功能上有区别吗?也就是说,与其在类的实例上调用方法,不如直接将该实例作为方法的参数传递呢?如果您只是省略了this 关键字,扩展方法不能做所有相同的事情吗?打字方式是唯一的优势吗?
【解决方案2】:

扩展方法允许扩展现有类,而无需依赖继承或更改类的源代码。这意味着如果你想在现有的 String 类中添加一些方法,你可以很容易地做到这一点。在决定是否使用扩展方法时,需要考虑以下几条规则:

  • 扩展方法不能用于覆盖现有方法

  • 与实例方法具有相同名称和签名的扩展方法将不会被调用

  • 扩展方法的概念不能应用于字段、属性或事件

  • 谨慎使用扩展方法....过度使用可能是一件坏事!

【讨论】:

    【解决方案3】:

    此链接http://geekswithblogs.net/BlackRabbitCoder/archive/2010/04/26/c-extension-methods---to-extend-or-not-to-extend.aspx 提供了有关何时使用扩展方法以及何时不使用的良好指导。

    引用这篇文章:

    一个好的扩展方法应该:
    - 适用于它所扩展类型的任何可能实例。
    - 简化逻辑并提高可读性/可维护性。
    - 适用于最具体的类型或适用的接口。
    - 在命名空间中隔离,以免污染 IntelliSense。

    【讨论】:

    • 是的......“应用于它扩展的类型的任何可能实例。”是一个重要因素。如果不是,那么某种实用程序/辅助方法可能更有意义。
    【解决方案4】:

    我会在有意义的时候使用扩展方法。如果您控制一个类及其代码,通常不需要扩展方法。

    如果您,扩展方法可能会很有用。

    我经常使用扩展方法的一个地方是 [Flags] 枚举。当您有一个基于标志的枚举时,需要一个相当大的表达式来确定枚举值是否具有特定的标志集。因此,每当我构建 [Flags] 枚举时,我都会构建以下扩展方法:

    [Flags]
    public enum MyEnum
    {
        FlagA,
        FlagB,
        // etc.
    }
    
    public static class MyEnumExt
    {
        public static bool HasFlags(this MyEnum item, MyEnum query)
        {
            return ((item & query) == query);
        }
    }
    

    这样我的代码看起来像:

    MyEnum flags = MyEnum.FlagA;
    if(flags.HasFlags(MyEnum.FlagA))
    {
      // handle FlagA
    }
    

    而不是:

    MyEnum flags = MyEnum.FlagA;
    if((flags & MyEnum.FlagA) == MyEnum.FlagA)
    {
      // handle FlagA
    }
    

    【讨论】:

      【解决方案5】:

      老实说,我想说什么时候是不是好主意比什么时候是好主意更容易解释。

      我认为,扩展方法的主要好处是它们可能增加您的方法的采用率。这是因为用户不必为了使用您的方法而实例化另一个类的实例,并且当开发人员正在为您正在扩展的类寻找方法时,智能感知会宣传您的方法。如果您试图让其他开发人员在您的公司中遵循新标准,这可能很重要。

      在考虑是否创建扩展方法时,请记住 SOLID 原则。

      S单一职责: - 你几乎总是至少用扩展方法弯曲单一责任原则,因为你正在处理已经是一个类的东西(你要么无法控制,要么太害怕触摸)。

      O笔/关闭原则: - 扩展方法不能被覆盖,这意味着您的方法可能没有充分“开放扩展”。

      Liskov替换原理: - 如果您有任何类型的继承结构,您将无法在子类型上使用扩展方法。

      I接口隔离原则: - 尽管您可以“扩展”一个接口,但您必须为该扩展提供一个具体的实现。所以你不能针对一个接口编程>可以在不同的上下文中以不同的方式实现(例如单元测试)

      D依存倒置原则: - 如果您的代码有任何依赖项,您将如何为工厂和单元测试公开这些依赖项(依赖项倒置原则)?

      最后,扩展方法只是穿着新衣服的静态方法。因此,静态方法(例如 线程安全、垃圾收集等)的所有困难都伴随着扩展方法在您实现时出现。

      因此,我会考虑将方法编写为扩展并重新考虑使用工厂和基本帮助程序类。

      如果您确实编写了扩展方法,请使其非常简单。尽量避免有任何依赖项(或将所有依赖项作为参数传递)。并注意在多线程环境中管理内存和锁定资源的方式。

      【讨论】:

      • 这个答案是软件工程通用性的模糊大杂烩,其中一些与扩展方法没有特别的联系(即它们同样适用于常规实例方法),还有一些所提出的主张实际上是不正确的。抱歉,这没有帮助。
      【解决方案6】:

      什么是扩展方法?

      扩展方法使您能够向现有类型添加方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。

      扩展方法是一种特殊的静态方法,但它们被调用时就好像它们是扩展类型上的实例方法一样。

      如何使用扩展方法?

      扩展方法是静态类的静态方法,其中“this”修饰符应用于第一个参数。第一个参数的类型将是扩展的类型。

      仅当您使用 using 指令将命名空间显式导入源代码时,扩展方法才在范围内。

      扩展方法的使用要点:

      1.扩展方法必须定义在顶级静态类中。

      2.与实例方法同名和签名的扩展方法不会被调用。

      3.扩展方法不能用于覆盖现有方法。

      4.扩展方法的概念不能应用于字段、属性或事件。

      5.过度使用扩展方法不是一种好的编程风格。

      【讨论】:

        【解决方案7】:

        当“Is-A”关系有意义时使用继承。继承会在类之间创建不需要的依赖关系。

        当我觉得“如果 XYZ 类有 ABC 方法该有多好”时,我会使用扩展方法。

        我记得最好的例子是当我需要将集合分成块时使用扩展方法。 这是详细信息。

        https://www.codingcrest.com/extension-method-in-c/

        【讨论】:

          猜你喜欢
          • 2010-11-11
          • 2014-02-15
          • 1970-01-01
          • 1970-01-01
          • 2017-03-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-12
          相关资源
          最近更新 更多