你什么时候使用扩展方法,分机.方法与继承?

48 .net c#

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

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

Mar*_*ell 58

使用扩展方法的时间:

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

作为第二点的例子; 你可能有一个扩展方法IList<T>(例如,Sort)可以完全使用现有IList<T>成员编写...所以为什么强迫任何人写任何东西?这是LINQ的基础块,并允许微软提供不破坏任何东西更多的功能.

时间使用扩展方法:

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

  • 我没有理解使用扩展方法****的第一点. (3认同)

小智 24

扩展方法允许扩展现有类,而不依赖于继承或必须更改类的源代码.这意味着如果要在现有的String类中添加一些方法,可以非常轻松地完成.在决定是否使用扩展方法时,需要考虑以下几条规则:

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

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

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

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


小智 8

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

引用本文:

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


Ran*_*pho 7

我有理由使用扩展方法.如果您控制一个类及其代码,通常不需要扩展方法.

如果不这样做,扩展方法可能会有用.

我经常使用扩展方法的一个地方是[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这样我的代码看起来像:

MyEnum flags = MyEnum.FlagA;
if(flags.HasFlags(MyEnum.FlagA))
{
  // handle FlagA
}
Run Code Online (Sandbox Code Playgroud)

而不是:

MyEnum flags = MyEnum.FlagA;
if((flags & MyEnum.FlagA) == MyEnum.FlagA)
{
  // handle FlagA
}
Run Code Online (Sandbox Code Playgroud)


小智 5

老实说,我想说,当它不是一个好主意时,比当它是一个好主意时更容易解释。

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

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

单一责任: - 你几乎总是至少使用扩展方法来改变单一责任原则,因为你正在附加已经是一个类的东西(你要么无法控制,要么太害怕接触)。

开放/关闭原则: - 扩展方法不能被重写,这意味着您的方法可能无法充分“开放扩展”。

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

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

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

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

因此,我会认真考虑编写一个方法作为扩展,并重新考虑使用工厂和基本帮助器类。

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

  • 这个答案给人的印象是软件工程一般性的模糊大杂烩,其中一些与扩展方法没有特殊的联系(即它们同样适用于常规实例方法),并且一些声明实际上是不正确的。抱歉,但这没有帮助。 (9认同)