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

时间:2010-07-06 21:03:59

标签: c# extension-methods

在你开始指向重复之前,我知道我已经阅读了关于扩展方法的几乎所有关于SO的帖子。我只是试着扮演魔鬼的拥护者一分钟,考虑替代我的工作意见。

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

我当然认为并且在SO上找到所有精彩的帖子,这些帖子显示了使用扩展方法的许多原因。不要忘记很多.net框架都使用它们。我们最终没有使用它,因为我被团队推翻了。

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

我真的想不出任何想法,但我想在此发帖,看看是否有人能想到为什么不应该使用这些原因。

5 个答案:

答案 0 :(得分:5)

只要你的某个类型的对象具有“普遍适用”的功能,无论其状态如何,扩展方法都是不错的选择。

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

public static XElement ToXElement(this XmlElement element) { }

public static XmlElement ToXmlElement(this XElement element) { }

一般来说,无论实例的状态或我们使用它的位置如何,这些都是对它们扩展的类型有效。

如果您的方法不符合该标准,则应该将其移动到更靠近特定情况始终为真或易于检查的上下文的辅助方法。

例如,开发人员最近提名这是一种扩展方法:

public static bool ParseYesNoBool(this string input) { }

这里有两个问题:首先,这将出现在应用程序的所有字符串中,即使这种情况下可能适用的字符串数量非常少。所以我们打破了第一条规则,因为无论国家如何,它都没用。类似地,但第二,此功能的使用者仅限于针对外部系统的一个特定连接器的单个解析器。因此,将特定于实现的功能推广到通用命名空间是没有意义的。这被降级为解析器中的辅助方法。

就可读性和调试而言,这对任何合理技能水平的开发人员来说都是不正确的。

答案 1 :(得分:1)

一般情况下,如果您控制程序集的源代码并添加该方法不会导致对现有代码的任何重大更改(例如,如果LINQ尚未通过扩展方法实现,则会出现这种情况)只是添加一个普通的方法。

答案 2 :(得分:1)

关于扩展方法的框架设计Guildelines部分的

This discussion包含一些很好的建议。我认为您的方案的相关部分是:

  

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

如果您的建议使用没有通过该测试,那么它应该被击落。

答案 3 :(得分:0)

我会说,当“他们不打算使代码更清晰”时,你应该避免使用它们。当然,一些代码(或编码风格)是否“更加清晰”在人与人之间变化很大,所以这几乎没用。 (我有一个老板说我们应该避免使用接口,因为他们使代码“过于复杂且难以理解”)

答案 4 :(得分:0)

  

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

每当您违反功能的意图和设计时,我建议您重新考虑使用扩展方法。当您不想使用Extension方法时,我会看到一些情况:

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

2)忘记Decorator Pattern您为班级创建的扩展方法的数量超过三个。我发现使用装饰对象组织/沟通和维护域/对象模型比使用扩展对象更容易。然而,情况恰恰相反:如果装饰对象的方法少于四个,我在项目中发现了很多几乎“空”的对象。

3)私有函数:私有函数用于修改(创建,删除等)对象,扩展方法用于表示类型,就像结构一样。如果您发现扩展名被分配给该类型的另一个实例,则它可能不应该在扩展名中。