当我第一次了解扩展方法时,我读到了以下内容:
通常,我们建议您实现扩展方法 谨慎,仅在必要时。尽可能使用客户端代码 必须扩展现有类型应该通过创建新类型来执行此操作 派生自现有类型。
但是,我无数次看到在各种生产代码库中非常自由地使用扩展方法。
当然,我的经验并不代表大多数人,但我想知道指南是否有转变,替代设计理念,或者我是否碰巧看到足够多的代码忽略了指南,让我这么想?
注意:我不是想引发一场辩论(这将立即导致这个问题结束) - 老实说,我一直想知道这个问题一段时间,觉得我得到答案的最佳机会就在SO上。
我认为所有这些亮点都是理论与实践之间的通常差异。 理论上我们应该谨慎使用它们,但在实践中我们没有。 从理论上讲,我们应该做很多我们在实践中不做的事情,在一般的生活中,而不仅仅是编程。
多态性不适用于扩展方法,因为它们在编译时受到限制。
ParentClass parentClass = new ParentClass();
ParentClass derivedClass = new DerivedClass();
如果这两个类都有一个名为 ExtensionMethod() 的扩展方法(我肯定见过试图模仿虚拟/覆盖方法的扩展方法),这两个调用都会调用父类的扩展方法:
parentClass.ExtensionMethod();
derivedClass.ExtensionMethod();
为了实际使用派生的扩展方法,您必须调用:
((DerivedClass)derivedClass).ExtensionMethod();
扩展类是一种很好的方法,但通常它不适用于使用第三方库的代码(这与教育/示例代码不同,这是生产代码的常见情况)。因此,如果有意义,请派生新类,但是当扩展方法使代码更具可读性时,请随意使用扩展方法。
有很多扩展方法的原因有很多:
- 通常,您无法扩展类来添加使产品代码更具可读性的方法。 即像字符串这样的值类型或像流这样的层次结构中的一些基类。
- 扩展方法是在不污染接口的情况下向接口添加方法的宝贵方法。LINQ 是它如何生成更具可读性的代码的很好的例子。
- 一些框架建议在特定情况下使用扩展方法。 即对于MVC,建议向HtmlHelper添加扩展。
使用扩展方法有利有弊。
优点:扩展方法可以视为访客模式(GoF)。因此,它利用了模式,即在不修改代码的情况下,我们可以扩展一些功能。
缺点:尽管有优点,但MSDN告诉谨慎使用扩展方法是,IMO,扩展方法在某些时候会导致问题。首先,如果扩展方法的对象与扩展具有不同的命名空间,我们应该知道它在哪里。它导致有时我们无法使用扩展中的一些重要功能。此外,我看到很多滥用扩展的代码。由于扩展是基于 Type 的,有时该类型的对象确实不需要扩展,但是在编码时,我们应该看到很多扩展方法。
[更新]
IMO,滥用扩展方法
- 对扩展方法
- 使用如此通用的类型,例如对象:如果有很多具有对象类型的扩展方法,并且该扩展只关注少数类型,这会让我们烦恼,因为每个对象都与方法链接。
与点运算符或误解的链接断开:让我举一个例子。有如下所示的代码,我们应该按顺序调用 Read 然后 Write 方法。但是,我们可以按相反的顺序调用这些方法。
public static string Read(this string message) { //do something return message; } public static string Write(this string message) { //do something return message; } public static void Method() { "message".Read().Write(); "message".Write().Read(); // this is problem! }