我在想,使用与接口相同命名空间中的扩展方法,您可以获得与多重继承类似的效果,因为您不需要在 10 个不同的类中以相同的方式实现相同接口的重复代码。
这样做有什么缺点?我认为优点很明显,缺点通常会在以后回来咬你。
我看到的一个缺点是扩展方法不能是虚拟的,因此您需要确保您确实希望它们对每个实例都以相同的方式实现。
我在想,使用与接口相同命名空间中的扩展方法,您可以获得与多重继承类似的效果,因为您不需要在 10 个不同的类中以相同的方式实现相同接口的重复代码。
这样做有什么缺点?我认为优点很明显,缺点通常会在以后回来咬你。
我看到的一个缺点是扩展方法不能是虚拟的,因此您需要确保您确实希望它们对每个实例都以相同的方式实现。
我看到通过扩展方法构建接口功能的问题是您不再实际实现接口,因此不能将对象用作接口类型。
假设我有一个采用 IBar 类型对象的方法。如果我通过扩展方法在类 Foo 上实现 IBar 接口,那么 Foo 不会从 IBar 派生并且不能与它互换使用(Liskov Substitution 原则)。当然,我得到了我想要添加到 Foo 的行为,但是我首先失去了创建接口的最重要的方面——能够定义一个可以由各种类以各种方式实现的抽象契约,以便依赖类不需要知道具体的实现。
如果我非常需要多重继承(到目前为止我没有它),我想我会使用组合来尽量减少代码重复的数量。
考虑这一点的一种体面方法是,实例方法是由对象完成的,而扩展方法是对对象完成的。我相当肯定框架设计指南说你应该尽可能地实现一个实例方法。
一个接口声明“我关心使用这个功能,但不关心它是如何实现的”。这使实施者可以自由选择方式。它将意图(公共 API)与机制(具有具体代码的类)分离。
由于这是接口的主要好处,因此完全将它们实现为扩展方法似乎违背了它们的目的。甚至IEnumerable<T>
有一个实例方法。
编辑:此外,对象旨在作用于它们包含的数据。扩展方法只能看到对象的公共 API(因为它们只是静态方法);您必须公开对象的所有状态才能使其工作(OO 否)。