许多 BCL 类都有方法和扩展方法。当 Microsoft 拥有其类的源代码时,选择 ExtensionMethods 而不是 Methods 的设计决策是什么?谢谢你,史密斯
3 回答
实际上,BCL 中的大多数扩展方法并不适用于类,而是适用于接口,这是扩展方法的关键力量。
例如,几乎所有的 LINQ to 对象都是作为IEnumerable<T>
接口的扩展实现的,而不是类的扩展List<T>, HashSet<T>
等等。
因为接口没有功能(只是一个契约),所以向接口添加扩展方法为您提供了一种访问接口本身的方法。当实现只需要知道其使用的接口而不是实现细节(本身)时,这尤其方便。
微软确实一直在他们的 BCL 类中添加新方法(当然,他们尽可能避免破坏性更改)。但我相信他们在 BCL 中使用的大多数扩展方法是在接口上,而不是用于添加可以通过新方法直接添加到类/结构中的功能。
因此,简而言之,当 Microsoft 选择向单个class
(或具有公共基类的系列)添加功能时,他们可能只是直接添加方法(所有条件都相同),但如果他们想将新方法应用于给定接口的所有实现,他们可能会在该接口上使用扩展方法。
还要记住这一点!因为微软给了我们扩展方法,它也适用于他们没有创建的类!例如,您创建的任何实现的类IEnumerable<T>
都可以获得 LINQ 的功能以及额外的好处,即使您没有继承公共基类等。
选择 ExtensionMethods 而不是 Methods 的设计决策是什么
在我看来,选择扩展方法的一个重要原因是它促进了 SOLID 的 Open/Closed 原则,即 open for extension close for modify
Microsoft 倾向于将扩展方法用于适用于各种不同代码库的功能。例如,LINQ 几乎完全作为扩展方法实现。(并且您指出的大多数(如果不是全部)方法都是通用 LINQ 方法,而不是特定于这些类)。
这有很多优点。首先,如果您不使用 LINQ,则不必包含对 LINQ 库的引用或 using。这减少了代码膨胀。
其次,LINQ 可以应用于任何实现 IEnumerable 的对象,包括您自己的代码(如果您实现了枚举器)。您不必像其他情况下那样编写此代码。
第三,它允许将功能分解为离散的单元,从而更好地分离关注点并使类更易于维护。
还有很多其他潜在的好处,但是这个列表应该足以清楚地表明扩展方法是实现这些方法的最佳方式。