Les méthodes C # qui peuvent être statiques doivent-elles être statiques?
Nous en discutions aujourd'hui et je suis en quelque sorte sur la clôture. Imaginez que vous ayez une longue méthode dont vous refactorisez quelques lignes. La nouvelle méthode prend probablement quelques variables locales de la méthode parente et renvoie une valeur. Cela signifie que cela pourrait être statique.
La question est: devrait- il être statique? Ce n'est pas statique par conception ou par choix, simplement par sa nature en ce sens qu'il ne fait référence à aucune valeur d'instance.
Réponses:
Ça dépend. Il existe vraiment 2 types de méthodes statiques:
Dans une base de code de taille petite à moyenne, vous pouvez vraiment traiter les deux méthodes de manière interchangeable.
Si vous avez une méthode qui appartient à la première catégorie (peut être statique) et que vous devez la modifier pour accéder à l'état de la classe, il est relativement simple de déterminer s'il est possible de transformer la méthode statique en méthode d'instance.
Dans une grande base de code, cependant, le grand nombre de sites d'appels peut rendre la recherche pour voir s'il est possible de convertir une méthode statique en une méthode non statique trop coûteuse. Plusieurs fois, les gens verront le nombre d'appels et diront "ok ... je ferais mieux de ne pas changer cette méthode, mais d'en créer une nouvelle qui fasse ce dont j'ai besoin".
Cela peut entraîner soit:
Ces deux choses sont mauvaises.
Donc, mon conseil serait que si vous avez une base de code de plus de 200K LOC, je ne rendrais les méthodes statiques que si ce sont des méthodes incontournables.
La refactorisation de non-statique à statique est relativement facile (ajoutez simplement un mot-clé), donc si vous voulez transformer un can-be-static en une véritable statique plus tard (lorsque vous avez besoin de ses fonctionnalités en dehors d'une instance), vous pouvez le faire. Cependant, le refactoring inverse, transformer un can-be-static en une méthode d'instance est BEAUCOUP plus cher.
Avec de grandes bases de code, il vaut mieux se tromper du côté de la facilité d'extension, plutôt que du côté de la pureté idéologique.
Donc, pour les grands projets, ne rendez pas les choses statiques à moins que vous n'en ayez besoin. Pour les petits projets, faites ce que vous préférez.
la source
Je n'en ferais pas un membre statique public de cette classe . La raison en est que le rendre public statique, c'est dire quelque chose sur le type de la classe: non seulement que «ce type sait comment faire ce comportement», mais aussi «il est de la responsabilité de ce type d'exécuter ce comportement». Et il y a de fortes chances que le comportement n'ait plus de relation réelle avec le type plus large.
Cela ne veut pas dire que je ne le rendrais pas du tout statique. Posez-vous la question suivante: la nouvelle méthode pourrait-elle logiquement appartenir ailleurs? Si vous pouvez répondre "oui" à cela, vous voudrez probablement le rendre statique (et le déplacer également). Même si ce n'est pas vrai, vous pouvez toujours le rendre statique. Ne le marquez pas
public
.Pour des raisons de commodité, vous pouvez au moins le marquer
internal
. Cela évite généralement de devoir déplacer la méthode si vous n'avez pas un accès facile à un type plus approprié, mais la laisse toujours accessible là où c'est nécessaire de manière à ce qu'elle n'apparaisse pas dans l'interface publique aux utilisateurs de votre classe .la source
Pas nécessairement.
Le déplacement des méthodes publiques de statiques vers non statiques est un changement radical et nécessiterait des changements pour tous vos appelants ou consommateurs. Si une méthode ressemble à une méthode d'instance, mais qu'elle n'utilise aucun membre d'instance, je suggérerais d'en faire une méthode d'instance comme mesure de pérennité.
la source
Oui. La raison "elle peut être statique" est qu'elle n'opère pas sur l'état de l'objet sur lequel elle est appelée. Ce n'est donc pas une méthode d'instance, mais une méthode de classe. S'il peut faire ce qu'il doit faire sans jamais accéder aux données de l'instance, alors il doit être statique.
la source
Oui, ça devrait. Il existe différentes mesures de couplage qui mesure la façon dont votre classe dépend d'autres choses, comme les autres classes, méthodes, etc. Faire statique des méthodes est un moyen de maintenir le degré de couplage vers le bas, puisque vous pouvez être sûr d' une méthode statique ne fait référence à aucune membres.
la source
Je pense que cela le rendrait un peu plus lisible si vous le marquiez comme statique ... Ensuite, quelqu'un qui viendrait saurait qu'il ne fait référence à aucune variable d'instance sans avoir à lire la fonction entière ...
la source
Personnellement, je suis un grand fan de l'apatridie. Votre méthode a-t-elle besoin d'accéder à l'état de la classe? Si la réponse est non (et c'est probablement non, sinon vous n'envisageriez pas d'en faire une méthode statique), alors oui, allez-y.
Aucun accès à l'état, c'est moins de maux de tête. Tout comme c'est une bonne idée de masquer les membres privés qui ne sont pas nécessaires par d'autres classes, c'est une bonne idée de cacher l'état aux membres qui n'en ont pas besoin. Un accès réduit peut signifier moins de bogues. En outre, cela facilite le threading car il est beaucoup plus facile de garder les membres statiques thread-safe. Il y a également une considération pour les performances car le runtime n'a pas besoin de passer une référence à cela en tant que paramètre pour les méthodes statiques.
Bien sûr, l'inconvénient est que si jamais vous constatez que votre méthode précédemment statique devra accéder à l'état pour une raison quelconque, vous devez le changer. Maintenant, je comprends que cela peut être un problème pour les API publiques, donc s'il s'agit d'une méthode publique dans une classe publique, vous devriez peut-être réfléchir un peu aux implications de cela. Pourtant, je n'ai jamais été confronté à une situation dans le monde réel où cela posait un problème, mais peut-être que j'ai juste de la chance.
Alors oui, allez-y, par tous les moyens.
la source
Les méthodes statiques sont plus rapides que les méthodes non statiques, donc oui, elles devraient être statiques si elles le peuvent et il n'y a aucune raison particulière de les laisser non statiques .
la source
Je suis surpris que si peu de personnes mentionnent l'encapsulation ici en fait. Une méthode d'instance aura automatiquement accès à tous les champs, propriétés et méthodes privés (instance). En plus de tous ceux protégés hérités des classes de base.
Lorsque vous écrivez du code, vous devez l'écrire de manière à exposer le moins possible et aussi à avoir accès au moins possible.
Donc, oui, il peut être important de rendre votre code rapide, ce qui se produirait si vous rendiez vos méthodes statiques, mais généralement plus important, c'est de rendre votre code aussi incapable de créer des bogues que possible. Une façon d'y parvenir est d'avoir accès à votre code le moins possible de "trucs privés".
Cela peut paraître hors de propos à première vue puisque l'OP parle évidemment de refactoring qui ne peut pas se tromper dans ce scénario et créer de nouveaux bugs, cependant ce code refactorisé doit être maintenu dans le futur et modifié ce qui fait que votre code a une attaque plus " surface "en ce qui concerne les nouveaux bogues s'il a accès aux membres de l'instance privée. Donc, en général, je pense que la conclusion ici est que "oui, la plupart de vos méthodes devraient être statiques" à moins qu'il n'y ait d'autres raisons de ne pas les avoir statiques. Et cela simplement parce que c'est "une meilleure utilisation de l'encapsulation et du masquage des données et crée un code" plus sûr "" ...
la source
Rendre quelque chose de statique simplement parce que vous le pouvez n'est pas une bonne idée. Les méthodes statiques doivent être statiques en raison de leur conception et non par hasard.
Comme Michael l'a dit, changer cela plus tard cassera le code qui l'utilise.
Cela dit, il semble que vous créez une fonction d'utilité privée pour la classe qui est, en fait, statique par conception.
la source
Si vous avez pu refactoriser quelques lignes et que la méthode résultante pourrait être statique, c'est probablement une indication que les lignes que vous avez extraites de cette méthode n'appartiennent pas du tout à la classe contenant, et vous devriez envisager de les déplacer dans leur propre classe.
la source
Personnellement, je n'aurais pas d'autre choix que de le rendre statique. Resharper émet un avertissement dans ce cas et notre PM a une règle "Aucun avertissement du Resharper".
la source
Cela dépend mais en général je ne rend pas ces méthodes statiques. Le code est toujours en train de changer et peut-être qu'un jour je voudrais rendre cette fonction virtuelle et la remplacer dans une sous-classe. Ou peut-être qu'un jour il devra référencer des variables d'instance. Il sera plus difficile de faire ces changements si chaque site d'appel doit être changé.
la source
Je suggère que la meilleure façon d'y penser est la suivante: si vous avez besoin d'une méthode de classe qui doit être appelée lorsqu'aucune instance de la classe n'est instanciée, ou maintient une sorte d'état global, alors statique est une bonne idée. Mais en général, je suggère que vous préfériez rendre les membres non statiques.
la source
Vous devriez penser à vos méthodes et classes:
Si les deux derniers sont «oui», alors votre méthode / classe devrait probablement être statique.
L'exemple le plus utilisé est probablement la
Math
classe. Chaque langage OO majeur l'a et toutes les méthodes sont statiques. Parce que vous devez pouvoir les utiliser n'importe où, n'importe quand, sans créer d'instance.Un autre bon exemple est la
Reverse()
méthode en C #.Il s'agit d'une méthode statique de la
Array
classe. Il inverse l'ordre de votre tableau.Code:
Il ne renvoie même rien, votre tableau est inversé, car tous les tableaux sont des instances de la classe Array.
la source
Tant que vous rendez la nouvelle méthode privée statique, ce n'est pas un changement radical. En fait, FxCop inclut ces conseils comme l'une de ses règles ( http://msdn.microsoft.com/en-us/library/ms245046(VS.80).aspx ), avec les informations suivantes:
Cela étant dit, le premier commentaire de David Kean résume plus succinctement les préoccupations en disant qu'il s'agit en fait plus d'être correct que de gagner en performance:
la source
Je transformerais certainement tout ce que je peux en statique pour une raison différente:
Les fonctions statiques, lorsqu'elles sont JIT, sont appelées sans paramètre "this". Cela signifie, par exemple, qu'une fonction non statique à 3 paramètres (méthode membre) est poussée avec 4 paramètres sur la pile.
La même fonction compilée en tant que fonction statique serait appelée avec 3 paramètres. Cela peut libérer des registres pour le JIT et économiser de l'espace dans la pile ...
la source
Je suis dans le camp "uniquement rendre les méthodes privées statiques". La création d'une méthode publique peut introduire un couplage dont vous ne voulez pas et peut diminuer la testabilité: vous ne pouvez pas stuber une méthode statique publique.
Si vous souhaitez tester unitaire une méthode qui utilise une méthode statique publique, vous finissez par tester également la méthode statique, ce qui n'est peut-être pas ce que vous souhaitez.
la source
Les méthodes intrinsèquement statiques qui, pour une raison quelconque, sont rendues non statiques sont tout simplement ennuyeuses. En être témoin:
J'appelle ma banque et je demande mon solde.
Ils demandent mon numéro de compte.
C'est suffisant. Méthode d'instance.
J'appelle ma banque et demande leur adresse postale.
Ils demandent mon numéro de compte.
WTF? Échec - aurait dû être une méthode statique.
la source
Je le regarde généralement dans une perspective fonctionnelle des fonctions pures. Doit-il s'agir d'une méthode d'instance? Sinon, vous pouvez avoir intérêt à forcer l'utilisateur à transmettre les variables et à ne pas modifier l'état de l'instance actuelle. (Eh bien, vous pouvez toujours modifier l'état, mais le but est de ne pas le faire par conception.) Je conçois généralement des méthodes d'instance en tant que membres publics et je fais de mon mieux pour rendre les membres privés statiques. Si nécessaire (vous pouvez ensuite les extraire plus facilement dans d'autres classes plus tard.
la source
Dans ces cas, j'ai tendance à déplacer la méthode vers une bibliothèque statique ou utils, donc je ne mélange pas le concept d '"objet" avec le concept de "classe"
la source