【发布时间】:2011-08-05 14:12:15
【问题描述】:
为什么微软对其创建的类使用扩展方法;而不是仅仅将方法添加到类中,或者创建子类?
【问题讨论】:
-
一般来说回答这个问题非常困难。请举一些具体的例子。
-
我在下面提到了这一点,但是
RouteCollection集合的IgnoreRoute()方法
标签: c# extension-methods
为什么微软对其创建的类使用扩展方法;而不是仅仅将方法添加到类中,或者创建子类?
【问题讨论】:
RouteCollection 集合的 IgnoreRoute() 方法
标签: c# extension-methods
微软这样做的原因有很多。最大的两个是:
扩展方法适用于接口,而不仅仅是类。如果 Microsoft 只是将 Linq 方法直接添加到 IEnumerable,那么它也需要该接口的每个具体实现来实现这些方法。通过使它们成为扩展方法,根据现有的 IEnumerable 行为编写,每个 IEnumerable 类都会自动获取它们。
对于 3.0 和 3.5 框架,核心 System.dll 是 2.0 库。 3.0 和 3.5 中的所有新内容都是在 System.Core 或其他相关库中添加的。例如,在 3.5 中存在但在 2.0 中不存在的 List 类中获取新方法的唯一方法是在 3.5 库中提供扩展方法。
【讨论】:
RouteCollection 上的IgnoreRoute() 是一种扩展方法,因为它旨在与 MVC 框架一起使用,而不是与核心 ASP.NET 应用程序一起使用。我的猜测是他们不想用非 MVC 应用程序不需要的方法污染 RouteCollection 类,同时仍然允许 MVC 应用程序使用该类。
我不确定这种方法是否一定有意义(例如,他们可能刚刚创建了一个子类);对于可能使用扩展方法的更一般的原因,其他人回答得很好。
【讨论】:
这是Non-Virtual Interface 模式的示例(类似于Template Method)。这是在具有多重(实现)继承的语言中使用的模式,而在 C# 中执行此操作的方法是使用扩展方法。
基本思想是您只有非虚拟和纯虚拟(抽象)方法。接口的实现者(或类/mixin 的继承者,在具有多重继承的语言中),实现一个小方法或一组方法(在本例中为 GetEnumerator),并作为回报获得大量依赖于它的方法一种抽象方法(如 Select、Where、Aggregate 等)
正如 Michael Edenfield 在他的回答中所说,如果我们想实现这种模式并且我们希望 IEnumerable 成为一个接口,我们需要使用扩展方法。把 IEnumerable 变成一个抽象类会很糟糕,因为它应该是一个非常低成本的基本接口,应该放在几乎任何集合上——实现 IEnumerable 不需要重新考虑类层次结构,它应该几乎是“免费的” ”。
【讨论】:
我认为主要原因是这些方法很容易扩展。例如,如果您使用 Linq 扩展方法,您可以轻松编写自己的扩展方法集(可能是 foreach 或某些特定的过滤器),这些方法将与 microsoft 方法一起使用:mylist.Where(...).MyFilter(...)。选择(...)
【讨论】:
我的两分钱:
因为扩展方法仅在 .NET 框架的更高版本中添加,他们已经拥有 .NET Framework 1、1.1、2.0 和更新版本,然后在某些时候他们添加了扩展方法,因此他们使用它们来丰富功能集现有类的顶部。
【讨论】: