C#如何缺less多重inheritance导致需要接口?

在C#编程语言中, Krzysztof Cwalina在注释中指出:

我们明确地决定不添加对多重inheritance的支持[…]缺乏多重inheritance迫使我们添加接口的概念,而接口的概念反过来又对框架的演化,更深的inheritance层次结构和其他许多问题负责问题。

接口是面向对象编程语言的核心概念。 我不遵循“强迫我们添加接口的概念”的意思,

Krzysztof是否意味着必须对使用否则将使用多重inheritance的接口进行某些devise决定? 或者,他的意思是说interface是由于缺乏多重inheritance而引入C#的? 你能提供一个例子吗?

接口只是一个没有数据成员的基类,只定义了public abstract方法。 例如,这将是C ++中的一个接口:

 class IFrobbable { public: virtual void Frob() = 0; } 

因此,当MI作为一种语言function可用时,您可以通过简单地从它们(也是C ++)派生出来来“实现”接口:

 class Widget : public IFrobbable, public IBrappable { // ... } 

在一般情况下的多重inheritance会产生许多问题和问题,这些问题和答案不一定有一个答案,甚至是一个好的定义“好”( 可怕的钻石 ,任何人?)。 多接口实现避免了这些问题中的大部分,因为“inheritance”一个接口的概念是一个非常有限的inheritance一个成熟的类的特殊情况。

这就是“迫使我们添加接口的概念”的地方:当仅限于单一inheritance时,你不能做很多的OOdevise,例如,当代码重用实际上是不能重用代码的严重问题OO最常见的论据。 你必须做更多的事情,下一步是添加多重inheritance,但仅限于满足接口约束的类。

所以,我解释了克日什托夫的话

在一般情况下的多重inheritance是一个非常棘手的问题,我们不能以令人满意的方式解决.NET的发展的现实约束。 但是,接口inheritance在OOP中处理起来也是非常重要的,所以我们的确把它放在了这个接口中。但是当然接口也带有一系列的问题,主要是关于BCL的结构。

来自Chris Brumme :

有很多原因我们不直接实现多个实现inheritance。 (如你所知,我们支持多接口inheritance)。

我认为Krzysztof Cwalina在引用中所说的不是接口本身的概念,而是将多接口inheritance作为多重inheritance的一种方法。

有几个原因,我们还没有提供多种实现inheritance的可兼容的,可validation的CLS兼容版本:

  1. 不同的语言实际上对MI的工作方式有不同的期望。 例如,冲突如何解决,重复的基地是合并还是重复。 在CLR中实施MI之前,我们必须对所有语言进行调查,找出共同的概念,并决定如何以语言中立的方式expression它们。 我们还需要决定MI是否属于CLS,这对于那些不想使用这个概念的语言(大概是VB.NET)意味着什么。 当然,这就是我们作为公共语言运行时所处理的业务,但是我们还没有做到这一点。

  2. MI真正适合的地方其实是相当小的。 在很多情况下,多接口inheritance可以完成工作。 在其他情况下,您可以使用封装和委派。 如果我们添加一个稍微不同的构造,比如mixin,那会更强大吗?

  3. 多个实现inheritance为实现注入了很多复杂性。 这种复杂性会影响到投射,布局,调度,字段访问,序列化,身份比较,可validation性,reflection,generics以及其他许多地方。

我认为你应该阅读Eric Lippert关于Interfaces 。 他的手脏了,所以我觉得他比其他人都清楚。

有时会有更糟的情况和最坏的情况。 你必须select不太坏的一个。

以下是链接的文章的副本:


他们只是为了确保所述函数(在接口中)在inheritance类中实现。

正确。 这是一个非常棒的好处来certificate这个function。 正如其他人所说,界面是实施某些方法,属性和事件的合同义务。 静态types语言的强大优势是编译器可以validation代码依赖的契约是否真的被满足。

也就是说,接口是代表合同义务的相当弱的方式。 如果您想要更强大和更灵活的方式来表示合同义务,请查看最新版本的Visual Studio附带的代码合同function。

C#是一门伟大的语言,但是有时它会让你感觉到,第一个微软创build了这个问题(不允许多重inheritance),然后提供了一个相当乏味的解决scheme。

那么我很高兴你喜欢它。

所有复杂的软件devise都是衡量相互矛盾的function的结果,并试图find“小甜点”,以较小的成本获得巨大的收益。 我们从痛苦的经历中学到,为了实现共享的目的而允许多重inheritance的语言,其利益相对较小,成本相对较高。 仅在不共享实现细节的接口上允许多重inheritance,在没有大部分成本的情况下,提供了多重inheritance的许多好处。

我认为克瓦利纳的语言有点强大,而且对历史也不完全准确。

请记住,接口是在C#之前,所以说“我们不得不添加接口来解决问题x”听起来不正确。 我认为接口会在默认情况下出现 – 它们必须是。

另外请记住,C#主要来源于C ++。 或者至less,参与创buildC#语言的人在C ++中拥有非常强的背景。 多重inheritance是C ++公认的恶梦领域。 inheritance自可能从commonm基类派生的多个类,确定哪个实现会优先等等。我的意思是,这是一个非常强大的特性,但是无疑会导致复杂的代码。

我怀疑他们放弃了C#的多重inheritance,因为他们(语言作者)知道如何纠缠一切,他们想避免这种情况。 同时请记住,当C#被引入时,它的一个卖点是它的清洁性(比Java更清洁,比C和C ++更清洁)。

顺便说一下,在C#开发的10多年中,我只希望多次inheritance一次。 一个UI组件,我想要inheritance一个视觉风格和一些共同的行为。 无论如何,我没有花太多时间才意识到我打算做的事情本来就是一个非常糟糕的devise。