为什么C#允许通过接口扩展方法而不是类来进行多重继承?

Ric*_*ver 12 c# inheritance extension-methods multiple-inheritance

我已经检查了其他问题,令人惊讶的是,这个问题似乎没有被问到.使用Extension方法,接口提供有限但真正的实现多重继承.这带来了Diamond问题,与基于类的多重继承相同.为什么这比基于类的多重继承更好或更可接受,这么多人似乎觉得这么可怕?它实际上似乎是一种更糟糕的实现多重继承的方式,因为扩展方法不能进入接口本身,甚至不能进入实现接口的类,但最终可能分散在多个静态实用程序类中.

Eric Lippert在他的博客(2009年10月5日上午9:29)似乎对扩展属性的概念持开放态度,甚至提到了扩展事件,扩展操作符,扩展构造函数(也称为"工厂模式")的可能性.因此可以进一步扩展通过接口的实现.

编辑:为了阐明一个类是否继承了两个接口,这两个接口都具有相同名称和类型参数的扩展方法,那么如果在没有显式命名接口的情况下调用方法,则会产生编译错误.考虑到这一点,我错了,因为这不是钻石问题.然而,考虑到这一点提出了一个问题,即钻石问题与其他歧义相比有多重要?为什么Diamond问题是如此困难,以至于它不能用简单的编译错误来获取,就像接口扩展方法类碰撞并且不能隐式解析一样?即使在基于类的多重继承中,也可能存在非基于Diamond的成员签名冲突.

Eri*_*ert 13

使用扩展方法,接口提供有限但真正的实现多重继承.

这句话是整个问题的基础,但我无法做出正面或反面,因此很难回答这个问题.

首先,让我们清楚地定义"继承".当我们说类型D继承自类型B时,我们的意思是B的每个成员也是D†的成员.这就是所有我们在C#中"继承"的意思.

类(或结构)从一个(††)基类继承成员.一个类可以实现任意数量的接口; 这与基类继承完全不同.类不需要具有与其实现的接口相同的成员集,因为该类可以使用显式接口实现来提供实现而无需成为类的成员.显式接口实现只能通过接口访问,并且不能以任何其他方式访问,因此将其视为从接口"继承"的类的"成员"将是奇怪的.

接口从任意数量的其他接口"继承"成员.从技术上讲,这可以被认为是继承; 基接口的成员是派生接口的成员.但我希望我们没有在规范中描述它; 我认为说接口不从基接口继承会更清楚; 相反,接口可能需要实现其他接口作为其合同的一部分.

既然我们已经解决了这个问题,那么扩展方法呢?扩展方法不是任何类型的继承; 扩展的类型不会获得任何新成员.扩展方法只是一种更愉快地编写对静态方法的调用的方法.

这带来了Diamond问题,与基于类的多重继承相同

目前还不清楚该句中"这个"是指什么.你指的是(1)实现多个接口的类,(2)从多个接口继承的接口,或者(3)关于扩展方法的东西,或者(4)完全不同的东西?我不明白钻石问题与你的问题有什么关系.你能澄清一下吗?

为什么这比基于类的多重继承更好或更可接受,这么多人似乎觉得这么可怕?

为什么是什么好?

我根本不理解这个问题,但似乎在某处有某种有用的问题.你能澄清一下这个问题吗?最好用一些简短的示例代码来演示您正在谈论的内容.


†不是每个成员.例如,构造函数和析构函数是成员,但不是可继承的成员.私有成员继承的,但可能无法通过名称访问.

††除了object,从零类继承.每个其他类都从一个类继承.


And*_*ber 8

任何实现多重继承的扩展方法的出现完全是一种错觉.他们不.

扩展方法是简单的编译器技巧.它们编译为普通的旧静态方法,这些方法看起来和工作方式与this从第一个参数中删除的方法一样.

考虑:

myObj.Extension();
...
public static class MyExtension
{
    public static void Extension(this MyObj myobj)
Run Code Online (Sandbox Code Playgroud)

调用扩展名等同于:

MyExtension.Extension(myObj);
Run Code Online (Sandbox Code Playgroud)

当然,您甚至可以在代码中调用它.


das*_*ght 5

C#类实现的接口列表是扁平化的,因此当一个类通过它实现的多个接口继承它来实现接口时,该类需要提供的实现数量仍然是一个.

例如,如果一个类实现了两个继承自的接口IDisposable,那么该类仍然Dispose()只需要实现一次.这与C++形成对比,在C++中,需要分别重写通过多个非虚拟继承路径从同一基类继承的函数.

扩展方法与此问题正交,因为它们提供的实现无法覆盖.我写了一篇关于扩展方法的博客文章及其在"横向"共享实现中的作用.我认为它们是一种以完全独立于通过类继承获得的"垂直"实现共享的方式提供功能的机制.