109 votes

Pourquoi c# implémente les méthodes comme non virtuelle par défaut ?

Contrairement à Java, pourquoi c# traite méthodes comme des fonctions non virtuelle par défaut ? Il est plus susceptible d’être un problème de performances plutôt que d’autres résultats possibles ?

Je me rappelle de lire un paragraphe de Anders Hejlsberg sur plusieurs avantages de que l’architecture existante est faire ressortir. Mais, qu’en est-il des effets secondaires ? Est-ce vraiment un bon compromis d’avoir des méthodes non virtuelles par défaut ?

103voto

Mehrdad Afshari Points 204872

Les classes doivent être conçues pour l’héritage pouvoir en profiter. Avoir des méthodes par défaut signifie que toutes les fonctions dans la classe peuvent être branchée sur et remplacée par une autre, qui n’est pas vraiment une bonne chose. Beaucoup de gens croient encore que les classes aurait dû être par défaut.

``méthodes peuvent également avoir une implication performance légère. Ce n’est pas susceptible d’être la principale raison, cependant.

94voto

mwardm Points 700

Je suis surpris qu'il semble y avoir un consensus ici que la non-virtuel par défaut est la bonne façon de faire les choses. Je vais descendre sur l'autre - je pense que pragmatique côté de la barrière.

La plupart des justifications de me lire comme la vieille "Si nous vous donnons le pouvoir vous risquez de vous blesser vous-même" argument. De programmeurs?!

Il me semble que le codeur qui ne savent pas (ou n'ont pas assez de temps) pour la conception de leur bibliothèque pour l'héritage et/ou de l'extensibilité est le codeur qui est produit exactement la bibliothèque, je suis susceptible de corriger ou ajuster exactement la bibliothèque où la possibilité de remplacer viendrait en plus utile.

Le nombre de fois où j'ai eu à écrire laid, désespérée de travail autour de code (ou de l'abandon de l'utilisation et de rouler ma propre solution alternative) parce que je ne peux pas remplacer loin, l'emporte de loin sur le nombre de fois où j'ai déjà été mordu (par exemple en Java) en substituant où le concepteur peut ne pas avoir pensé que je pourrais.

Non-virtuelle-par-défaut me rend la vie plus difficile.

Mise à JOUR: Il a été souligné [justement] que je n'ai pas réellement répondre à la question. - Et avec mes excuses pour être un peu tard....

J'ai un peu envie d'être capable d'écrire quelque chose lapidaires comme "C# implémente les méthodes non-virtuel par défaut, car une mauvaise décision qui accordait de l'importance des programmes les plus fortement que les programmeurs". (Je pense que ça pourrait être quelque peu justifié sur la base de certains des autres réponses à cette question à la performance (optimisation prématurée, anyone?), ou de garantir le comportement des classes.)

Cependant, je me rends compte que je venais d'énoncer mon opinion et pas de réponse définitive que le Débordement de la Pile de désirs. Sûrement, je pensais que, au plus haut niveau de l'définitive (mais inutile) la réponse est:

Ils sont non-virtuel par défaut, parce que la langue-les concepteurs ont une décision à prendre et c'est ce qu'ils ont choisi.

Maintenant, je suppose que la raison exacte, ils ont pris cette décision, nous allons jamais.... oh, attendez! La transcription d'une conversation!

Il semblerait donc que les réponses et les commentaires ici sur les dangers de l'impérieuse d'Api et de la nécessité de concevoir explicitement pour l'héritage sont sur la bonne voie, mais sont tous manquent un important aspect temporel: Anders " la principale préoccupation était sur le maintien d'une classe ou de l'API de contrat implicite entre les versions. Et je pense qu'il est plus préoccupé par permettant aux .Net / C# plate-forme pour le changement sous le code plutôt que préoccupés par l'utilisateur changer le code sur le dessus de la plate-forme. (Et son "pragmatique" point de vue est à l'exact opposé de la mienne, parce qu'il est à la recherche de l'autre côté.)

(Mais ils ne pourraient pas avoir choisi virtuel par défaut, puis parsemé de "finale" par le biais de la base de code? C'est peut-être pas tout à fait la même chose.. et Anders, c'est clairement plus intelligent que moi, donc je vais laisser mentir.)

20voto

Zifre Points 14109

Parce que c’est trop facile d’oublier qu’une méthode peut être substituée et pas conçu pour cela. C# vous fait penser avant que vous fassiez c’est virtuel. Selon moi, qu'il s’agit d’une décision de grand dessein. Certaines personnes (comme Jon Skeet) ont même dit que les classes devraient être scellés par défaut.

13voto

Trillian Points 2922

Pour résumer ce que d'autres ont dit, il ya quelques raisons:

1- En C#, il y a beaucoup de choses dans la syntaxe et de la sémantique qui viennent directement à partir de C++. Le fait que les méthodes non-virtuel par défaut en C++ influencé C#.

2- le fait que chaque méthode virtuelle par défaut est un souci de performances, car chaque appel de méthode doit utiliser l'objet de la Table Virtuelle. De plus, cela limite fortement le Juste-À-Temps capacité du compilateur associé méthodes et d'effectuer d'autres types d'optimisation.

3- le Plus important, si les méthodes ne sont pas virtuels par défaut, vous pouvez garantir le comportement de vos classes. Quand ils sont virtuels par défaut, comme en Java, on ne peut même pas garantir qu'une simple méthode de lecture fera comme prévu, car il pourrait être remplacé à tout faire dans une classe dérivée (bien sûr, vous pouvez, et devez, faire de la méthode et/ou de la classe finale).

On peut se demander, comme Zifre mentionné, pourquoi le langage C# ne pas aller plus loin et de rendre les classes scellé par défaut. Cela fait partie de l'ensemble du débat sur les problèmes de mise en œuvre de l'héritage, qui est un sujet très intéressant.

9voto

Schildmeijer Points 10975

C# est influencée par le C++ (et plus). C++ ne permet pas la distribution dynamique (fonctions virtuelles) par défaut. Un (bon?) argument pour ce qui est de la question: "Combien de fois avez-vous mettre en œuvre les classes qui sont membres d'une catégorie hiérarchique?". Une autre raison d'éviter l'activation de la dynamique d'expédition par défaut est l'empreinte mémoire. Une classe sans un pointeur virtuel (vpointer) pointant vers une table virtuelle, est bien sûr plus petit que la classe correspondante, avec la fin de la liaison activée.

Le problème de performance n'est pas si facile de dire "oui" ou "non". La raison pour cela est le Juste À Temps (JIT) compilation qui est un moment de l'exécution de l'optimisation en C#.

Un autre, question similaire à propos de "vitesse de virtuel appels.."

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X