12
votes

Pourquoi les méthodes virtuelles devraient-elles être explicitement remplacées dans C #?

Pourquoi les méthodes virtuelles doivent-elles être explicitement remplacées dans C #?


0 commentaires

5 Réponses :


5
votes

Parce que cela rend le code plus lisible: xxx

en C ++, FOO peut ou non être une méthode virtuelle, nous ne pouvons pas dire en regardant la définition. En C #, nous savons qu'une méthode est virtuelle (ou non) car il existe un mot-clé virtuel ou de remplacement.

Le commentaire de Jason ci-dessous est une meilleure réponse.

(édité pour la clarté )


7 commentaires

... et il donne à Intellisense la capacité de nous aider à remplacer une méthode. Tapez "remplacement" et Intellisense apparaît avec un choix et se remplit même dans toute la signature de la méthode pour nous. Quelle est la génie?


... et, surtout, il permet au compilateur de nous dire lorsque nous vous trompons (par exemple, si vous ajoutez un paramètre à la méthode de la classe de base en C ++, il enfreint toutes les classes dérivées, mais vous n'avez aucun moyen de le savoir - Une cause de quelques bugs vraiment méchants de tracer des bugs, car les morceaux du comportement de classe dérivé cesse d'arrêter de travailler tranquillement. En C #, cela donne une erreur pour chaque dérogation qui ne remplace rien)


"En C ++, nous ne pouvons pas dire en regardant la définition." - en regardant la définition, nous pouvons dire que ce n'est pas le tout C ++.


@stakx: que WhoShing sonne que vous avez entendu, vous avez manqué le point.


Je pense que je faire obtenez le point, Maintenant que je sais qu'il y en a un. Dans l'ensemble, je trouve cette réponse plus confuse que possible. (-1)


Je dis que cette réponse est fausse, comme l'ajout remplacer fait que le code se comporte assez différent.


@stakx: Vous avez raison, j'aurais pu l'avoir écrit en C ++, ce qui aurait été plus clair @dykam: C # ne vous permet pas de remplacer sans le mot clé. S'il n'y a pas de mot clé de remplacement, il ne peut y avoir une méthode avec cette signature pour remplacer. Il n'y a pas de "comportement différent" car ils sont deux choses différentes (repoussement, ne pas repousser).



16
votes

En déclarant une méthode comme virtuel , vous êtes indiquer votre intention que la méthode peut être remplacée dans une classe dérivée.

En déclarant votre méthode d'implémentation sous forme de remplacement , votre indique votre intention que vous remplacez une méthode

En exigeant que le mot-clé soit utilisé pour remplacer une méthode virtuelle, les concepteurs de la langue encouragent la clarté, en vous obligeant à énoncer vos intentions.


6 commentaires

@George: Parce que vous ne pouvez utiliser le modificateur abstrait que dans des classes abstraites.


@George Stocker - parce que vous ne voudrez peut-être pas marquer votre classe entière comme abstrait (la classe a besoin du modificateur abstrait pour avoir des méthodes abstraites).


Le mot clé n'est pas requis - voir ma réponse.


@Slaks: c'est est si vous voulez remplacer.


Cette réponse ne mentionne pas le comportement par défaut nouveau du tout. C'est-à-dire que lorsque vous ne remplissez pas, vous cachez la mise en œuvre de la base.


(Copié mon commentaire ici, car c'est un point important. Aurait dû faire une réponse à laquelle je suppose :-) ... la substitution permet également au compilateur de nous dire quand nous faisons une erreur (par exemple, si vous ajoutez un paramètre à la base méthode de classe en C ++, il enfreint toutes les classes dérivées, mais vous n'avez aucun moyen de le savoir - une cause de quelques bugs vraiment désagréables, car les morceaux du comportement de classe dérivé cesseront simplement de travailler. En C #, cela donne une erreur pour chaque remplacer cela ne subsiste plus rien)



11
votes

Si vous n'ajoutez pas le mot-clé , la méthode sera masquée (comme s'il y avait le mot-clé nouveau ), non remplacé.

Par exemple : xxx

Ce code imprime base . Si vous ajoutez remplacer à la mise en œuvre dérivé , le code imprimera dérivé .

Vous ne pouvez pas le faire en C ++ avec une méthode virtuelle. ( Il n'y a aucun moyen de masquer une méthode virtuelle C ++ sans le remplacer )


1 commentaires

Je conviens que cela ne devrait pas être légal et devrait lancer une erreur au lieu d'un avertissement. (Edit: Quelqu'un a retiré son commentaire au-dessus de celui-ci).



1
votes

Toutes les méthodes virtuelles ne doivent pas être remplacées, bien que toutes les méthodes abstraites soient (et doivent) être. En ce qui concerne la raison pour laquelle le mot-clé «remplacement» est explicite, c'est-à-dire parce que le dépassement et la dissimulation se comportent différemment. Une méthode de masquage n'est pas appelée à travers une référence à une classe de base, tandis qu'une méthode remplacée est. C'est pourquoi le compilateur met en garde spécifiquement sur la manière dont vous devez utiliser le mot-clé «Nouveau» dans le cas où vous vous cachez plutôt que de remplacer.


0 commentaires

10
votes

C'est parce que les membres de l'équipe C # sont tous des programmeurs spécialisés C ++. Et savoir à quel point ce bogue particulier est: xxx

Il est beaucoup plus courant que vous pourriez penser. La classe dérivée est toujours déclarée dans un autre fichier de code source. Vous n'allez généralement pas ce mauvais tout de suite, cela se produit lorsque vous refacteur. Pas de peep du compilateur, le code fonctionne assez normal, ne fait que ce que vous attendez. Vous pouvez le regarder pendant une heure ou une journée et ne pas voir le bogue.

Cela ne peut jamais arriver dans un programme C #. Même géré C ++ a adopté cette syntaxe, brisant avec une syntaxe native C ++ intentionnellement. Toujours un choix courageux. IntelliSense prend la piqûre du verbiage supplémentaire.

Il y a beaucoup de peaux de syntaxe en C # qui ressemblent à ce type de syntaxe d'évitement de bugs.


modifier: et le reste de la C ++ Communauté a accepté et adopté le mot clé remplacer par dans la nouvelle spécification de langue C ++ 11.


1 commentaires

+1 Meilleure réponse IMO car il explique le "pourquoi" derrière la décision de conception linguistique au lieu de "comment les appels virtuels fonctionnent" comme des réponses nominales plus élevées ... PS. @Hans je semble se heurter à beaucoup de réponses pertinentes écrites par vous ces jours-ci :)