74 votes

Dois-je marquer toutes les méthodes virtuelles?

En Java, vous pouvez marquer méthode finale de la rendre impossible à remplacer.

En C#, vous devez marquer méthode virtuelle pour le rendre possible de remplacer.

Veut-il dire qu'en C#, vous devez marquer toutes les méthodes virtuelles (à l'exception de quelques-uns que vous ne voulez pas être remplacée), depuis plus de chances que vous ne savez pas de quelle manière votre classe peut être héréditaire?

144voto

Eric Lippert Points 300275

En C#, vous devez marquer méthode virtuelle pour le rendre possible de remplacer. Veut-il dire qu'en C#, vous devez marquer toutes les méthodes virtuelles (à l'exception de quelques-uns que vous ne voulez pas être remplacée), depuis plus de chances que vous ne savez pas de quelle manière votre classe peut être héréditaire?

Pas de. Si la langue concepteurs pensaient que virtuel doit avoir été la valeur par défaut alors qu'il aurait été la valeur par défaut.

Overridablility est une fonction, et, comme toutes les fonctions qu'il a des coûts. Les coûts d'une remplacable méthode sont considérables: il y a des gros de la conception, de la mise en œuvre et les coûts de test, en particulier s'il existe une "sensibilité" à la classe; les méthodes virtuelles sont des moyens de présenter les tiers non testés code dans un système et qui a un impact sur la sécurité.

Si vous ne savez pas comment vous avez l'intention de votre classe à être héréditaire, alors ne publiez pas votre classe parce que vous n'avez pas terminé la conception de il encore. Votre modèle d'extensibilité est certainement quelque chose que vous devriez savoir à l'avance le temps; il doit profondément influencer votre conception de la stratégie de test et de.

Je plaide pour que toutes les classes être scellé et toutes les méthodes de non-virtuel jusqu'à ce que vous avez dans le monde réel centrées sur le client la raison pour desceller ou de faire une méthode virtuelle.

Fondamentalement, votre question est "je suis ignorant de la façon dont mes clients ont l'intention de consommer de ma classe; dois-je donc faire de manière arbitraire extensible?" Non, vous devez devenir bien informé! Vous ne demandez pas "je ne sais pas comment mes clients vont utiliser ma classe, donc si je fais toutes mes propriétés en lecture-écriture? Et je dois faire tous mes méthodes de lecture-écriture des propriétés de type délégué pour que mes utilisateurs peuvent remplacer n'importe quelle méthode avec leur propre mise en œuvre?" Non, ne pas faire aucune de ces choses jusqu'à ce que vous avez la preuve que l'utilisateur a réellement besoin de cette capacité! Passer votre temps précieux à la conception, le test et la mise en œuvre de fonctionnalités que les utilisateurs veulent et ont besoin, et de le faire à partir d'une position de la connaissance.

31voto

Patrick Klug Points 5320

À mon avis, actuellement accepté de répondre inutilement dogmatique.

Fait est que vous ne marquez pas une méthode virtual, d'autres ne peuvent pas remplacer son comportement et lorsque vous marquez une classe en tant que sealed autres ne peuvent pas hériter de la classe. Cela peut causer des douleurs importantes. Je ne sais pas combien de fois j'ai maudit une API pour le marquage des classes sealed ou non des méthodes de marquage virtual tout simplement parce qu'ils n'avaient pas prévu mon cas d'utilisation.

Théoriquement, il pourrait être la bonne approche pour autoriser uniquement la redéfinition des méthodes et héritant des classes qui sont destinés à être remplacée et héréditaire, mais dans la pratique il est impossible de prévoir tous les scénarios possibles et à moins que votre projet de sécurité des si critiques il n'y a vraiment pas une bonne raison d'être si fermé.

  1. Si vous n'avez pas une très bonne raison, alors ne marque pas les classes sealed.
  2. Ne marque pas à chaque méthode virtual comme cela semble un peu overkill et il est inhabituel en C#, mais marque les principales méthodes d'une classe qui contiennent le comportement en tant que virtual.

Une manière de faire de l'appel est de regarder le nom de la méthode ou la propriété. Un GetLength() la méthode sur une Liste fait exactement ce que son nom l'indique et il ne permet pas pour autant de l'interprétation. Changer sa mise en œuvre serait susceptible de ne pas être très transparent, de sorte marquant comme virtual est probablement inutile. Le marquage de l' Add méthode virtuelle est beaucoup plus utile que quelqu'un pourrait créer une Liste spéciale qui accepte uniquement certains objets à l'aide de la méthode Add etc. Un autre exemple sont les contrôles personnalisés. Vous voulez rendre la principale méthode de tirage virtual alors que d'autres peuvent utiliser la majeure partie du comportement et il suffit de changer le look, mais vous ne serait probablement pas remplacer les propriétés X et Y de.

En fin de compte, vous avez souvent de ne pas avoir à prendre cette décision tout de suite. Dans un projet interne, où vous pouvez facilement changer le code de toute façon je ne voudrais pas vous soucier de ces choses. Si une méthode doit être remplacé, vous pouvez toujours faire virtuel lorsque cela se produit. Au contraire, si le projet est une API ou de la bibliothèque qui est consommé par d'autres et de temps à mettre à jour, il paie certainement à réfléchir sur les classes et les méthodes pourrait être utile. Dans ce cas, je pense que c'est mieux d'être ouverte plutôt que strictement fermé.

22voto

John Saunders Points 118808

Non! Parce que vous ne savez pas comment votre classe est héritée, vous devriez seulement la marque d'une méthode virtual si vous savez que vous voulez qu'il soit remplacé.

5voto

nunespascal Points 12686

Pas de. Seules les méthodes que vous souhaitez classes dérivées pour spécifier devrait être virtuel.

Virtuel n'est pas définitive.

Pour éviter d'écraser une méthode virtuelle en c# vous utilisez sealed

public class MyClass
{
    public sealed override void MyFinalMethod() {...}
}

3voto

irreputable Points 25577

Nous pouvons évoquer des raisons/nouveau camp, soit, mais c'est totalement inutile.

En Java il y a des millions d'involontaires de non-finale méthodes publiques, mais nous nous entendons très peu d'histoires d'horreur.

En C# il y a des millions de scellés des méthodes publiques, et nous nous entendons très peu d'histoires d'horreur.

Il n'est donc pas une grosse affaire - le besoin de redéfinir une méthode public est rare, il est donc discutable.


Cela me rappelle un autre argument - si une variable locale doit être définitive par défaut. C'est une bonne idée, mais nous ne pouvons pas exagérer combien il est utile. Il y a des milliards de variables locales qui pourraient l'être, mais ne sont pas, en finale, mais il a été montré pour être un réel problème.

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