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

时间:2009-04-24 19:55:25

标签: c# .net

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

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

6 个答案:

答案 0 :(得分:56)

使用扩展方法的时间:

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

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

的时间使用扩展方法:

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

答案 1 :(得分:23)

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

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

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

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

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

答案 2 :(得分: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);
    }
}

这样我的代码就像:

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

而不是:

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

答案 3 :(得分:7)

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

引用本文:

  

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

答案 4 :(得分:1)

老实说,我会说当它是 NOT 这个好主意时比解释它更容易。

我认为,扩展方法的主要好处是可以 增加方法的采用 。这是因为用户不必实例化另一个类的实例以便使用您的方法,并且当开发人员正在为您正在扩展的类寻找方法时,intellisense将通告您的方法。如果您试图让其他开发人员遵循公司的新标准,这可能很重要。

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

  

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

     

O 笔/关闭原则:    - 无法覆盖扩展方法,这意味着您的方法可能没有充分“开放”以进行扩展&#34;。

     

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

     

nterface隔离原则:    - 虽然你可以&#34;延伸&#34;一个接口,你必须为该扩展提供具体的实现。因此,您无法编程接口&gt;可以在不同的上下文中以不同方式实现(例如,单元测试)

     

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

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

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

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

答案 5 :(得分:1)

什么是扩展方法?

扩展方法使您可以将方法添加到现有类型,而无需创建新的派生类型,重新编译或修改原始类型。

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

如何使用扩展方法?

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

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

使用扩展方法的重要要点:

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

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

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

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

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