为什么vb.net不支持多重继承?
我见过一些关于为什么 c# 不实现多重继承的讨论,但很少有人讨论为什么 vb 不支持多重继承。我知道 c# 和 vb 都被编译为中间语言,因此它们都需要共享类似的限制。
VB 中缺乏多重继承似乎被认为是 dot net 中缺乏该功能的原因之一。有谁知道为什么VB不支持多重继承?我希望能有一些历史教训并讨论为什么 VB 从未考虑过这一点。
I've seen some discussion on why c# does not implement multiple inheritance but very little as to why it isn't supported in vb. I understand that both c# and vb are compiled down to intermediary language and so they both need to share similar restrictions.
The lack of multiple inheritance in VB seems to have been given as one reason for the lack of the feature in dot net. Does anyone know why VB doesn't support multiple inheritance? I'm hoping for a bit of history lesson and discussion on why this was never considered for VB.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
它未在 CLR 中实现,因此在 VB.NET 等符合 CLS 的语言中不可用。 Microsoft 的工程师(包括 C# 首席架构师 Anders Hejlsberg)似乎有一个普遍共识,即潜在的好处不值得付出成本和实施的复杂性。 Chris Brumme,当时 .NET 团队的一位杰出工程师,早在 2004 年就说过这样的话:
[链接]
底线是我不会屏住呼吸。
目前,通过继承多个接口并将实现委托给所包含的类实例,您可以获得多个实现继承的一些(如果不是大部分)好处。这需要更多的工作,但这是我们目前最好的。
我还应该指出,我多年来一直全职编写 C++,并且只在自己的设计中利用了几次多重继承。当我需要它时它很方便,但说实话,我发现自己在 C# 中并不经常需要它。
It isn't implemented in the CLR so it isn't available in CLS-compliant languages like VB.NET. There seems to be a general consensus among engineers at Microsoft, including Anders Hejlsberg, C# lead architect, that the potential benefits are not worth the cost and complexity of implementation. Chris Brumme, a distinguished engineer on the .NET team at the time, said this back in 2004:
[Link]
Bottom line is I would not hold my breath.
For now, you can gain some if not most of the benefits of multiple implementation inheritance by inheriting multiple interfaces and delegating the implementation to a contained class instance. It's a little more work but it is the best we have right now.
I should also note that I wrote C++ full-time for several years and only leveraged multiple inheritance a couple of times in my own designs. It was handy when I needed it, but honestly I don't find myself wishing for it in C# very often.
所有 dotNET 语言共享通用类型系统,并且 CTS 不支持多重继承。 VB 或 C# 等特定语言无法自行添加此功能,否则它将与 dotNET 的其余部分不兼容。最多一种语言可能会选择忽略/隐藏这样的功能。
我不知道为什么没有包含它,但值得注意的是大多数语言不支持它。我只知道 C++,虽然基本应用程序很简单并且有时很有用,但它也带来了大量特殊的语法和规则。并不是每个人都认为它值得这个价格。
All dotNET languages share a Common Type System, and that CTS does not support multiple inheritance. A specific language like VB or C# cannot add this on its own, it would become incompatible with the rest of dotNET. At the most a language might select to ignore/hide such a feature.
I don't know exactly why this wasn't included but it's worth noticing that most languages don't support it. I only know of C++, and while the basic application is simple and sometimes useful it also bring a boatload of special syntax and rules along. Not everybody considers it worth the price.
MI(多重继承)的缺乏与语言设计和预期宿主 (CLR) 密切相关:
1) MI/SI 的差异对于语言来说非常重要,因此它非常重要。以后很难(或者可能不可能)“将其添加为功能”。
2) 至于预期的主机:虽然可以为 CLR 编写一种 MI 语言(就像可以为 CLR 编写一种带有延续等的语言一样——但它可以完成)的问题是,这样做时,您会失去与所有其他“.NET”语言的互操作性。
可以改装到 CLR 中的一种更简单的“MI”形式是通过编译时 MRO 折叠处理特征(这就是 Scala 支持 JVM 上的 Traits)。然而,这仍然需要对语言进行重大重新设计/重新思考,对于像 VB(.NET) 这样经过“审查”的东西,祝你好运:-) 必须确保它与现有代码兼容对语言进行改进时是一件大事。
The lack of MI (Multiple Inheritance) is greatly tied to both the language-design and the intended host (CLR):
1) The difference in MI/SI is so fundamental to a language that it is very difficult (or perhaps impossible) to 'add it as a feature' later.
2) As for the intended host: while it would be possible to write a MI language for the CLR (just as it would be possible to write a language with continuations, etc, for the CLR -- it can be done) is that, in doing so, you lose interoperability with all the other ".NET" languages.
A much easier form of "MI" that can be retrofitted into the CLR is Traits handled via compile-time MRO collapsing (This is how Scala supports Traits on the JVM). However, this still requires major redesign/rethink of the language, and for something as 'vetted' as VB(.NET), good luck :-) Having to make sure that it plays nice with existing code is a big deal when adding improvements to a language.
还有许多其他技术被证明比 MI 优越得多,例如组合。即使在像 C++ 这样支持 MI 的语言中,实际看到一个类从两个非抽象基类多重继承的情况也是极其罕见的。
There are many other techniques that prove to be vastly superior to MI, such as composition. Even in languages like C++ that do support MI, it's incredibly rare to actually see a class multiply inherit from two non-abstract base classes.
为什么 C# 或 VB.NET 不支持多重继承
http://royalarun.blogspot.in/2013/05/why-c-or-vbnet-doesnt-support-multiple.html
1)第一个原因是模糊性钻石问题,考虑类 A 有 foo() 方法,然后 B 和 C 从 A 派生,并且有自己的 foo() 实现,现在类 D 使用多重继承从 B 和 C 派生,如果我们只引用 foo() 编译器将无法决定应该调用哪个 foo() 。这也称为钻石问题,因为这种继承场景的结构类似于 4 边钻石,见下文
在我看来,即使我们删除钻石类 A 的顶部头并允许多重继承,我们也会看到这个歧义问题。
有时,如果你向面试官给出这个原因,他会问 C++ 是否可以支持多重继承,而不是 c# 或 vb.net。在这种情况下,我会尝试向他解释我在下面给出的第二个原因,这不是因为技术困难但更多的是可维护和更清晰的设计是驱动因素,尽管这只能由任何 java 设计人员确认,我们只能推测。维基百科链接对使用多重继承时如何由于钻石问题而出现不同语言地址问题有一些很好的解释。
2)第二个对我来说更令人信服的原因是,多重继承确实使设计复杂化,并在转换、构造函数链接等过程中产生问题,并且考虑到需要多重继承的场景并不多,因此明智的决定是省略它简单。 C# 也通过支持接口的单一继承来避免这种歧义。由于接口只有方法声明并且不提供任何实现,因此只有特定方法的一种实现,因此不会有任何歧义。
Why C# or VB.NET doesn't support multiple inheritance
http://royalarun.blogspot.in/2013/05/why-c-or-vbnet-doesnt-support-multiple.html
1) First reason is ambiguity around Diamond problem, consider a class A has foo() method and then B and C derived from A and has there own foo() implementation and now class D derive from B and C using multiple inheritance and if we refer just foo() compiler will not be able to decide which foo() it should invoke. This is also called Diamond problem because structure on this inheritance scenario is similar to 4 edge diamond, see below
In my opinion even if we remove the top head of diamond class A and allow multiple inheritances we will see this problem of ambiguity.
Some times if you give this reason to interviewer he asks if C++ can support multiple inheritance than why not c# oR vb.net.In that case I would try to explain him the second reason which I have given below that its not because of technical difficulty but more to maintainable and clearer design was driving factor though this can only be confirmed by any of java designer and we can just speculate. Wikipedia link has some good explanation on how different language address problem arises due to diamond problem while using multiple inheritances.
2) Second and more convincing reason to me is that multiple inheritances does complicate the design and creates problem during casting, constructor chaining etc and given that there are not many scenario on which you need multiple inheritance its wise decision to omit it for the sake of simplicity. Also c# and avoids this ambiguity by supporting single inheritance with interfaces. Since interface only have method declaration and doesn't provide any implementation there will only be just one implementation of specific method hence there would not be any ambiguity.
假设类型
B
有一个虚拟方法m
,类型X
和Y
实现不同,尽管两种实现都链接到 < code>base.m()、D
派生自X
和Y
,但没有定义自己的实现,而George
是D
的一个实例。类X
将期望任何派生类都不会在不执行该方法自己的实现的情况下访问Bm()
,并且类Y
将有一个类似的期望。编译器无论做什么都不会违反这样的期望。如果从类型D
到B
的向上转换需要经过类型X
或Y
,那么进行的转换通过X
可以使用X
的方法,通过Y
的转换可以使用Y
的方法,但对D
的引用将无法被需要引用B
(或者就此而言,一个Object
)的代码直接使用。要求只有接口可以多重继承,并且每个实现接口的类型必须提供所有方法的实现几乎与提供广义多重继承一样好,但不会导致相同的歧义。Suppose type
B
has a virtual methodm
which typesX
andY
implement differently, though both implementations chain tobase.m()
,D
derives fromX
andY
without defining its own implementation, andGeorge
is an instance ofD
. ClassX
will expect that no derived class will accessB.m()
without going through its own implementation of that method, and classY
will have a similar expectation. There is nothing the compiler could haveCType(George,B).m()
do which would not violate such expectations. If upcasts from typeD
toB
were required to go through typeX
orY
, then the cast that went throughX
could useX
's method and the cast that went throughY
could useY
's method, but a reference toD
would then not be directly usable by code which expects a reference toB
(or, for that matter, anObject
). Requiring that only interfaces can be multiply inherited, and that every type which implements an interface must provide implementations of all the methods is almost as good as providing generalized multiple inheritance, but doesn't cause the same ambiguities.