2010-05-03 7 views
1

J'ai vu une discussion sur les raisons pour lesquelles C# n'implémente pas l'héritage multiple mais très peu sur les raisons pour lesquelles il n'est pas supporté par vb. Je comprends que les deux C# et vb sont compilés en langage intermédiaire et donc ils ont tous deux besoin de partager des restrictions similaires.pourquoi vb.net ne supporte pas l'héritage multiple?

L'absence d'héritage multiple dans VB semble avoir été donnée comme une des raisons de l'absence de la fonctionnalité dans dot net. Est-ce que quelqu'un sait pourquoi VB ne prend pas en charge l'héritage multiple? J'espère un peu de leçon d'histoire et de discussion sur pourquoi cela n'a jamais été considéré pour VB.

+0

Vous l'entendrez probablement parler de C# parce que C# est plus proche de C++ où MI est supporté. D'un autre côté, l'un des principaux objectifs de VB en tant que langage de programmation était la simplicité plutôt que la complexité, de sorte que la plupart des programmeurs ne s'attendaient pas à ce que VB supporte MI. –

Répondre

14

Il n'est pas implémenté dans le CLR, il n'est donc pas disponible dans les langages compatibles CLS tels que VB.NET. Il semble y avoir un consensus général parmi les ingénieurs de Microsoft, y compris Anders Hejlsberg, architecte en chef de C#, que les avantages potentiels ne valent pas le coût et la complexité de la mise en œuvre. Chris Brumme, ingénieur distingué de l'équipe .NET à l'époque, a dit ce en 2004:

Il y a plusieurs raisons pour lesquelles nous n'avons pas fourni une version four-in, vérifiable, conforme CLS de mise en œuvre multiple héritage:

  1. Différentes langues ont des attentes différentes quant à la façon dont MI fonctionne. Par exemple, comment les conflits sont résolus et si les bases dupliquées sont fusionnées ou redondantes. Avant de pouvoir implémenter l'IM dans le CLR, nous devons faire un tour d'horizon de toutes les langues, trouver les concepts communs et décider comment les exprimer de manière neutre. Nous devrons également décider si le MI doit appartenir au CLS et ce que cela signifierait pour les langages qui ne veulent pas ce concept (vraisemblablement VB.NET, par exemple). Bien sûr, c'est l'affaire dans laquelle nous sommes en tant que langue courante, mais nous n'avons pas encore réussi à le faire pour MI.

  2. Le nombre d'endroits où MI est vraiment approprié est en fait assez petit. Dans de nombreux cas, l'héritage de plusieurs interfaces peut faire le travail à la place. Dans d'autres cas, vous pouvez utiliser l'encapsulation et la délégation. Si nous devions ajouter une construction légèrement différente, comme les mixines, cela serait-il réellement plus puissant?

  3. L'héritage d'implémentation multiple injecte beaucoup de complexité dans l'implémentation. Cette complexité a un impact sur la distribution, la mise en page, l'envoi, l'accès au champ, la sérialisation, les comparaisons d'identité, la vérifiabilité, la réflexion, les génériques et probablement beaucoup d'autres endroits.

Il n'est pas du tout évident que cette fonctionnalité serait rentable. C'est quelque chose qu'on nous demande souvent. C'est quelque chose sur lequel nous n'avons pas fait preuve de diligence raisonnable. Mais mon instinct me dit qu'après avoir fait un examen approfondi, nous allons quand même décider de laisser la fonctionnalité inappliquée.

[Link]

Bottom line est que je ne retiendrais pas mon souffle. Pour l'instant, vous pouvez obtenir quelques-uns, sinon la plupart, des avantages de l'héritage d'implémentation multiple en héritant de plusieurs interfaces et en déléguant l'implémentation à une instance de classe contenue. C'est un peu plus de travail mais c'est le meilleur que nous avons en ce moment.

Je devrais également noter que j'ai écrit C++ à temps plein pendant plusieurs années et seulement exploité l'héritage multiple plusieurs fois dans mes propres conceptions. C'était pratique quand j'en avais besoin, mais honnêtement, je ne me retrouve pas très souvent en train de le souhaiter en C#.

+1

: //blogs.msdn.com/csharpfaq/default.aspx? p = 7 – R0MANARMY

+0

Par ailleurs, les mixins seraient plus cool. –

4

Tous les langages dotNET partagent un système de type commun et CTS ne prend pas en charge l'héritage multiple. Un langage spécifique comme VB ou C# ne peut pas l'ajouter seul, il deviendrait incompatible avec le reste de dotNET. Au maximum, une langue peut choisir d'ignorer/cacher une telle fonctionnalité.

Je ne sais pas exactement pourquoi cela n'a pas été inclus, mais il est intéressant de noter que la plupart des langues ne le prennent pas en charge. Je ne connais que le C++, et bien que l'application de base soit simple et parfois utile, elle apporte également une charge de syntaxe et de règles spéciales. Tout le monde ne considère pas que ça vaut le prix.

+0

Et généralement sous C++, il est préférable que son héritage multiple ne soit utilisé que pour prendre en charge le modèle une base + plusieurs interfaces, et ne branche que si vous avez vraiment besoin d'une classe de deux classes de base – SztupY

2

L'absence de MI (héritage multiple) est fortement liée à la fois la langue conception et l'hôte prévu (CLR):

1) La différence de MI/SI est si fondamental à une langue il est très difficile (voire impossible) de l'ajouter plus tard. 2) Comme pour l'hôte prévu: alors qu'il serait serait possible d'écrire un langage MI pour le CLR (tout comme il serait possible d'écrire une langue avec des suites, etc, pour le CLR - il peut être fait) est que, ce faisant, vous perdez l'interopérabilité avec tous les autres langages ".NET". Traits traités par l'intermédiaire de l'effondrement MRO au moment de la compilation (C'est ainsi que Scala prend en charge les Traits sur la JVM). Une forme beaucoup plus facile de «MI» qui peut être réajustée dans le CLR. Cependant, cela nécessite encore majeur redesign/repenser la langue, et pour quelque chose d'aussi 'Vetted' que VB (.NET), bonne chance :-) Avoir à faire en sorte qu'il joue bien avec le code existant est un gros problème quand ajouter des améliorations à une langue.

0

Il existe de nombreuses autres techniques qui s'avèrent être largement supérieures à l'IM, telles que la composition. Même dans des langages comme C++ qui supportent MI, il est incroyablement rare de voir une classe hériter de deux classes de base non abstraites.

0

Pourquoi C# ou VB.NET ne supporte pas l'héritage multiple

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

1) La première raison est l'ambiguïté autour problème Diamond, considèrent une classe A a la méthode foo(), puis B et C est dérivé de A et a sa propre implémentation de foo() et maintenant la classe D dérive de B et C en utilisant l'héritage multiple et si nous nous référons au compilateur foo(), nous ne pourrons pas décider quel foo() il devrait invoquer. Il est également appelé problème de diamant parce que la structure de ce scénario d'héritage est similaire à 4 bord diamant, voir ci-dessous

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

À mon avis, même si l'on enlève la tête en haut de la classe diamant A et permettent plusieurs héritages nous verrons ce problème d'ambiguïté.

Parfois, si vous donnez cette raison à l'intervieweur, il demande si C++ peut supporter l'héritage multiple que pourquoi pas C# oR vb.net.Dans ce cas, je vais essayer de lui expliquer la deuxième raison que j'ai donnée ci-dessous en raison de la difficulté technique, mais plus à la conception maintenable et plus claire a été le facteur déterminant si cela peut seulement être confirmé par n'importe quel concepteur de Java et nous pouvons juste spéculer. Lien Wikipedia a une bonne explication sur la façon dont le problème d'adresse de langue différente se pose en raison de problème de diamant tout en utilisant plusieurs héritages.2) Une deuxième raison plus convaincante pour moi est que les héritages multiples compliquent la conception et créent un problème lors de la conversion, du chaînage de constructeurs etc et étant donné qu'il n'y a pas beaucoup de scénarios pour lesquels vous avez besoin de plusieurs héritages pour des raisons de simplicité. Aussi C# et évite cette ambiguïté en supportant l'héritage unique avec des interfaces. Puisque l'interface n'a qu'une déclaration de méthode et ne fournit aucune implémentation, il n'y aura qu'une seule implémentation de méthode spécifique, donc il n'y aurait pas d'ambiguïté.

0

Type Suppose B a une méthode virtuelle m quels types X et Y mettre en œuvre différemment, bien que les deux chaînes de mises en œuvre à base.m(), D dérive de X et Y sans définir sa propre mise en œuvre et George est une instance de D. La classe X s'attendra à ce qu'aucune classe dérivée n'accède à B.m() sans passer par sa propre implémentation de cette méthode, et la classe Y aura une attente similaire. Il n'y a rien que le compilateur puisse faire qui ne viole pas de telles attentes. Si upcasts de le type D à B devaient passer par le type X ou Y, le casting qui a traversé X pourrait utiliser « la méthode de et la distribution qui est passé par Y pourrait utiliser Y » X méthode s, mais une référence à D le ferait alors ne pas être directement utilisable par le code qui attend une référence à B (ou, d'ailleurs, un Object). Exiger que seules les interfaces puissent être héritées à plusieurs reprises, et que chaque type qui implémente une interface doit fournir des implémentations de toutes les méthodes est presque aussi bon que de fournir un héritage multiple généralisé, mais ne provoque pas les mêmes ambiguïtés.

Questions connexes