可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
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:
There are several reasons we haven't provided a baked-in, verifiable, CLS-compliant version of multiple implementation inheritance:
Different languages actually have different expectations for how MI works. For example, how conflicts are resolved and whether duplicate bases are merged or redundant. Before we can implement MI in the CLR, we have to do a survey of all the languages, figure out the common concepts, and decide how to express them in a language-neutral manner. We would also have to decide whether MI belongs in the CLS and what this would mean for languages that don't want this concept (presumably VB.NET, for example). Of course, that's the business we are in as a common language runtime, but we haven't got around to doing it for MI yet.
The number of places where MI is truly appropriate is actually quite small. In many cases, multiple interface inheritance can get the job done instead. In other cases, you may be able to use encapsulation and delegation. If we were to add a slightly different construct, like mixins, would that actually be more powerful?
Multiple implementation inheritance injects a lot of complexity into the implementation. This complexity impacts casting, layout, dispatch, field access, serialization, identity comparisons, verifiability, reflection, generics, and probably lots of other places.
It's not at all clear that this feature would pay for itself. It's something we are often asked about. It's something we haven't done due diligence on. But my gut tells me that, after we've done a deep examination, we'll still decide to leave the feature unimplemented.
[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.
回答2:
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.
回答3:
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.
回答4:
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.
回答5:
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
A foo()
/ \
/ \
foo() B C foo()
\ /
\ /
D
foo()
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.
回答6:
Suppose type B
has a virtual method m
which types X
and Y
implement differently, though both implementations chain to base.m()
, D
derives from X
and Y
without defining its own implementation, and George
is an instance of D
. Class X
will expect that no derived class will access B.m()
without going through its own implementation of that method, and class Y
will have a similar expectation. There is nothing the compiler could have CType(George,B).m()
do which would not violate such expectations. If upcasts from type D
to B
were required to go through type X
or Y
, then the cast that went through X
could use X
's method and the cast that went through Y
could use Y
's method, but a reference to D
would then not be directly usable by code which expects a reference to B
(or, for that matter, an Object
). 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.