为什么vb.net不支持多重继承?

发布于 2024-08-31 12:21:47 字数 185 浏览 10 评论 0原文

我见过一些关于为什么 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

烂人 2024-09-07 12:21:47

它未在 CLR 中实现,因此在 VB.NET 等符合 CLS 的语言中不可用。 Microsoft 的工程师(包括 C# 首席架构师 Anders Hejlsberg)似乎有一个普遍共识,即潜在的好处不值得付出成本和实施的复杂性。 Chris Brumme,当时 .NET 团队的一位杰出工程师,早在 2004 年就说过这样的话:

我们没有提供内置的、可验证的、符合 CLS 的多重实现继承版本有几个原因:

  1. 不同的语言实际上对 MI 的工作方式有不同的期望。例如,如何解决冲突以及是否合并重复碱基或冗余碱基。在我们在 CLR 中实现 MI 之前,我们必须对所有语言进行调查,找出共同的概念,并决定如何以语言中立的方式表达它们。我们还必须决定 MI 是否属于 CLS,以及这对于不需要此概念的语言(例如 VB.NET)意味着什么。当然,这就是我们作为公共语言运行时所从事的业务,但我们还没有时间为 MI 做这件事。

  2. 真正适合 MI 的地方其实很少。在许多情况下,多个接口继承可以完成这项工作。在其他情况下,您也许可以使用封装和委托。如果我们添加一个稍微不同的结构,比如 mixins,那实际上会更强大吗?

  3. 多重实现继承给实现注入了很多复杂性。这种复杂性会影响转换、布局、调度、字段访问、序列化、身份比较、可验证性、反射、泛型以及可能的许多其他地方。

目前还不清楚此功能是否能收回成本。这是我们经常被问到的问题。这是我们还没有进行尽职调查的事情。但我的直觉告诉我,在我们进行深入检查后,我们仍然会决定不实现该功能。

[链接]

底线是我不会屏住呼吸。

目前,通过继承多个接口并将实现委托给所包含的类实例,您可以获得多个实现继承的一些(如果不是大部分)好处。这需要更多的工作,但这是我们目前最好的。

我还应该指出,我多年来一直全职编写 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:

There are several reasons we haven't provided a baked-in, verifiable, CLS-compliant version of multiple implementation inheritance:

  1. 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.

  2. 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?

  3. 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.

千纸鹤 2024-09-07 12:21:47

所有 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.

无声情话 2024-09-07 12:21:47

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.

岁月如刀 2024-09-07 12:21:47

还有许多其他技术被证明比 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.

聽兲甴掵 2024-09-07 12:21:47

为什么 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 foo()
/\
/\
foo() BC foo()
\ /
\ /
D
富()

在我看来,即使我们删除钻石类 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

      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.

快乐很简单 2024-09-07 12:21:47

假设类型 B 有一个虚拟方法 m,类型 XY 实现不同,尽管两种实现都链接到 < code>base.m()、D 派生自 XY,但没有定义自己的实现,而 GeorgeD 的一个实例。类 X 将期望任何派生类都不会在不执行该方法自己的实现的情况下访问 Bm(),并且类 Y 将有一个类似的期望。编译器无论做什么都不会违反这样的期望。如果从类型 DB 的向上转换需要经过类型 XY,那么进行的转换通过X可以使用X的方法,通过Y的转换可以使用Y的方法,但对 D 的引用将无法被需要引用 B(或者就此而言,一个 Object)的代码直接使用。要求只有接口可以多重继承,并且每个实现接口的类型必须提供所有方法的实现几乎与提供广义多重继承一样好,但不会导致相同的歧义。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文