代码之家  ›  专栏  ›  技术社区  ›  yamspog

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

  •  1
  • yamspog  · 技术社区  · 16 年前

    我已经看到一些关于为什么c不实现多重继承的讨论,但是很少有关于为什么vb不支持它的讨论。我知道C和VB都被编译成中间语言,所以它们都需要共享类似的限制。

    vb缺乏多重继承性似乎是dot net缺乏这种特性的一个原因。有人知道为什么vb不支持多重继承吗?我希望能上点历史课,讨论一下为什么vb从来没有考虑过这个问题。

    6 回复  |  直到 12 年前
        1
  •  14
  •   Simon P Stevens    16 年前

    它不是在clr中实现的,因此在vb.net等符合cls的语言中不可用。微软的工程师们,包括首席架构师anders hejlsberg,似乎达成了一个普遍的共识,即潜在的好处不值得实现的成本和复杂性。当时.NET团队的杰出工程师Chris Brumme早在2004年就说过:

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

    1. 不同的语言实际上对mi的工作方式有不同的期望。例如,如何解决冲突以及是否合并重复基或冗余基。在clr中实现mi之前,我们必须对所有语言做一个调查,找出共同的概念,并决定如何以与语言无关的方式表达它们。我们还必须决定mi是否属于cls,这对于不需要这个概念的语言意味着什么(例如,可能是vb.net)。当然,这是我们作为一个公共语言运行时所从事的业务,但是我们还没有时间为mi做这项工作。

    2. 实际上,mi真正合适的地方非常少。在许多情况下,多接口继承可以代替此工作。在其他情况下,您可以使用封装和委托。如果我们添加一个稍有不同的构造,比如mixins,那实际上会更强大吗?

    3. 多实现继承为实现注入了许多复杂性。这种复杂性会影响转换、布局、分派、字段访问、序列化、身份比较、可验证性、反射、泛型,可能还会影响许多其他地方。

    目前还不清楚这项功能是否能为自己买单。这是我们经常被问到的问题。这是我们没有尽职调查的问题。但我的直觉告诉我,在我们做了深入的检查之后,我们仍然会决定不让这个功能实现。

    [ Link ]

    底线是我不会屏住呼吸。

    现在,通过继承多个接口并将实现委托给包含的类实例,您可以获得多实现继承的一些好处(如果不是大多数好处的话)。这是一个多一点的工作,但它是我们现在最好的。

    我还应该注意到,我在几年内编写了C++全职,并且在我自己的设计中只使用了多次继承。当我需要它的时候,它很方便,但老实说,我发现自己并不经常希望它在C。

        2
  •  4
  •   Henk Holterman    16 年前

    所有dotnet语言都共享一个公共类型系统,cts不支持多重继承。像vb或c这样的特定语言不能单独添加它,它将与dotnet的其他部分不兼容。一种语言最多可以选择忽略/隐藏这样的功能。

    我不知道为什么不包括它,但值得注意的是,大多数语言都不支持它。我只知道C++,而基本应用程序是简单的,有时是有用的,它也带来了一系列特殊的语法和规则。不是每个人都认为这值得。

        3
  •  2
  •   user166390    16 年前

    缺少mi(多重继承)与语言设计和目标主机(clr)有很大关系:

    1)mi/si的差异是 如此基本 对于一种很难(或可能不可能)在以后“将其作为功能添加”的语言来说。

    2)对于预期的主机:当它 可以为CLR编写一种MI语言(就像为CLR编写一种具有连续性的语言一样——这是可以做到的)是这样做的, 你失去了互操作性 与所有其他“.net”语言一起使用。

    一种更简单的“mi”形式可以被更新到clr中,它是通过编译时mro折叠来处理的特性(这就是如何 Scala 支持jvm上的特征)。然而,这仍然需要 专业 重新设计/重新思考语言,对于像vb(.net)这样经过“审查”的东西,祝你好运:-)在对语言进行改进时,必须确保它能很好地处理现有代码是一件大事。

        4
  •  0
  •   Puppy    16 年前

    有许多其他的技术被证明远远优于mi,比如构图。即使在支持C++的C++语言中,实际看到一个类从两个非抽象基类中继承继承是非常罕见的。

        5
  •  0
  •   Arun Prakash    12 年前

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

    http://royalarun.blogspot.in/2013/05/why-c-or-vbnet-doesnt-support-multiple.html

    1)第一个原因是diamond问题的模糊性,假设一个类a有foo()方法,然后b和c从a派生,并且有自己的foo()实现,现在d类使用多重继承从b和c派生,如果我们只引用foo()编译器将无法决定哪个foo()iT应该调用。这也被称为diamond问题,因为这个继承场景的结构类似于4edge diamond,请参见下面

          A foo()
           / \
          /   \  
    foo() B     C foo()  
          \   /  
           \ /  
            D
           foo()
    

    在我看来,即使我们删除了diamond类a的顶部头部并允许多个继承,我们也会看到这个模棱两可的问题。

    有时,如果你给面试官这个理由,他会问C++是否能支持多重继承,而不是为什么不支持C或VB.NET。在这种情况下,我会尝试向他解释我在下面给出的第二个原因,那不是因为技术上的困难,而是更多的是可维护的和更清晰的设计。驱动因素虽然这只能由Java设计器中的任何一个确认,我们可以推测。wikipedia link对使用多个继承时由于diamond问题而产生的不同语言地址问题有一些很好的解释。

    2)对我来说,第二个也是更令人信服的原因是,多重继承确实会使设计复杂化,并在转换、构造函数链接等过程中产生问题,而且考虑到需要多重继承的场景并不多,为了简单起见,明智的决定是省略它。同时,通过支持带有接口的单继承来避免这种不确定性。由于接口只有方法声明,并且不提供任何实现,因此只有一个特定方法的实现,因此不会有任何歧义。

        6
  •  0
  •   supercat    12 年前

    假设类型 B 有一个虚拟方法 m 哪些类型 X Y 以不同的方式实现,尽管两种实现都链接到 base.m() , D 源自 X Y 没有定义自己的实现,以及 George D . 等级 X 将预期没有派生类将访问 B.m() 不经过它自己的方法实现,并且类 Y 会有类似的期待。编译器什么都没有 CType(George,B).m() 这样做不会违背这种期望。如果从类型向上转换 D 必须通过类型 X Y ,然后经过的演员 X 可以利用 X 他的方法和演员阵容 Y 可以利用 Y 的方法,但引用 D 如果代码希望引用 (或就此而言, Object )只要求接口可以被多重继承,并且实现接口的每种类型必须提供所有方法的实现,这几乎与提供广义多重继承一样好,但不会导致相同的歧义。