代码之家  ›  专栏  ›  技术社区  ›  spinon

什么时候应该避免扩展方法?

  •  8
  • spinon  · 技术社区  · 14 年前

    在你开始向我指出重复之前,我已经阅读了几乎所有关于扩展方法的文章。我只是想做一个魔鬼代言人,考虑一下我工作意见的替代方案。

    最近我在做一个项目,需要一个方法作为接口的基础。所以我建议我们写一个扩展方法,它被击落了。说它增加了复杂性和调试难度。

    当然,我坚持了下去,找到了所有精彩的帖子,展示了为什么要使用扩展方法的许多原因。别忘了很多.net框架都使用它们。我们最终没有使用它,因为我被球队否决了。

    但后来它让我思考,是否有时可以使用扩展方法,但不应该使用?

    5 回复  |  直到 14 年前
        1
  •  5
  •   Rex M    14 年前

    任何时候你有一个函数 “一般适用”

    例如,今天我在我们的代码库中添加了两个新的扩展方法:

    public static XElement ToXElement(this XmlElement element) { }
    
    public static XmlElement ToXmlElement(this XElement element) { }
    

    如果您的方法不满足该条件,则可能应该将其移到更接近上下文的助手方法,在该上下文中,特定情况始终为true或易于检查。

    例如,一位开发人员最近指定此方法作为扩展方法:

    public static bool ParseYesNoBool(this string input) { }
    

    这里有两个问题:第一,这将出现在应用程序中的所有字符串上,即使可能成为这种情况候选的字符串数量非常少。所以我们打破了第一条规则,不管是什么状态,它都没有用。类似地,但第二,此功能的使用者仅限于外部系统的一个特定连接器的单个解析器。因此,将特定于实现的功能提升到通用名称空间是没有意义的。已将其降级为解析器中的助手方法。

        2
  •  1
  •   heisenberg    14 年前

    一般来说,如果您控制程序集的源代码,并且添加方法不会对现有代码造成任何破坏性的更改(例如,如果没有通过扩展方法实现LINQ,就会出现这种情况),那么最好只添加一个普通方法。

        3
  •  1
  •   Jamie Ide    14 年前

    This discussion 对框架设计的Guildelines一节中的扩展方法给出了一些很好的建议。我认为你的方案的相关部分是:

    提供与接口的每个实现相关的助手功能,如果所述功能可以用核心接口编写的话。

    如果你提议的用法没有通过测试,那么它应该被删除。

        4
  •  0
  •   James Curran    14 年前

        5
  •  0
  •   Lucas B    14 年前

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

    任何时候你打破了这个特性的意图和设计,我都会建议你重新考虑使用扩展方法。我看到一些不想使用扩展方法的情况:

    更改对象模型以允许扩展方法 :要在其上创建扩展的类是抽象类。这将要求您要么使每个继承的类成为自己的扩展版本,要么从类中删除抽象。无论哪种方式,您都在更改对象模型以使用扩展方法。

    2) Decorator Pattern :

    3) 私人职能 :私有函数是用来修改(创建、删除等)对象和扩展方法是用来使用类型的,很像结构。如果您发现扩展正在分配给该类型的另一个实例,那么它可能不应该在扩展中。