web-dev-qa-db-fra.com

La méthode peut être rendue statique, mais devrait-elle?

Resharper aime souligner plusieurs fonctions par page asp.net qui pourraient être rendues statiques. Est-ce que cela m'aide de les rendre statiques? Devrais-je les rendre statiques et les déplacer vers une classe d'utilitaires?

351
dlamblin

Méthodes statiques et méthodes d'instance
10.2.5 Membres statiques et d'instance de la spécification du langage C # explique la différence. En règle générale, les méthodes statiques peuvent apporter une très petite amélioration des performances par rapport aux méthodes d'instance, mais uniquement dans des situations quelque peu extrêmes (voir cette réponse pour plus de détails à ce sujet).

La règle CA1822 dans FxCop ou Code Analysis indique:

"Après [marquer les membres comme statiques], le compilateur émettra des sites d'appels non virtuels à ces membres, ce qui empêchera une vérification au moment de l'exécution de chaque appel garantissant que le pointeur de l'objet en cours est non nul. un gain de performance mesurable pour le code sensible à la performance. Dans certains cas, l'impossibilité d'accéder à l'instance d'objet en cours représente un problème de correction. "

Classe d'utilitaires
Vous ne devez pas les déplacer vers une classe d’utilitaires à moins que cela ne soit logique dans votre conception. Si la méthode statique se rapporte à un type particulier, comme une méthode ToRadians(double degrees) à une classe représentant des angles, il est logique que cette méthode existe en tant que membre statique de ce type (remarque, il s'agit d'un exemple compliqué à des fins de démonstration).

235
Jeff Yates

Les performances, la pollution des espaces de noms, etc. sont, à mon avis, tous secondaires. Demandez-vous ce qui est logique. La méthode fonctionne-t-elle logiquement sur une instance du type ou est-elle liée au type lui-même? Si c'est le dernier cas, faites-en une méthode statique. Déplacez-le uniquement dans une classe d'utilitaires s'il est lié à un type qui n'est pas sous votre contrôle.

Parfois, il existe des méthodes qui agissent logiquement sur une instance mais n'utilisent pas l'un des états de l'instance encore. Par exemple, si vous construisiez un système de fichiers et que vous aviez le concept de répertoire, mais que vous ne l'aviez pas encore implémenté, vous pourriez écrire une propriété renvoyant le type d'objet du système de fichiers, et ce serait toujours juste. "fichier" - mais il est lié logiquement à l'instance et devrait donc être une méthode d'instance. Ceci est également important si vous voulez rendre la méthode virtuelle - votre implémentation particulière peut ne nécessiter aucun état, mais les classes dérivées peuvent en avoir besoin. (Par exemple, demander à une collection si elle est en lecture seule ou non - vous n'avez peut-être pas encore implémenté de formulaire en lecture seule, mais il s'agit clairement d'une propriété de la collection elle-même, et non du type.)

252
Jon Skeet

En marquant une méthode comme static dans une classe, il est évident qu’elle n’utilise aucun membre d’instance, ce qui peut être utile lorsque l’on parcourt le code.

Vous n'avez pas nécessairement besoin de le déplacer dans une autre classe, sauf si cette classe est censée être partagée par une autre classe aussi étroitement associée, sur le plan conceptuel.

54
Mark Cidade

Je suis sûr que cela ne se produit pas dans votre cas, mais une "mauvaise odeur" que j'ai vue dans certains codes que j'ai dû subir à travers le maintien utilise énormément de méthodes statiques.

Malheureusement, c'étaient des méthodes statiques supposant un état d'application particulier. (Pourquoi bien sûr, nous n’aurons qu’un seul utilisateur par application! Pourquoi ne pas laisser la classe User en tenir compte dans les variables statiques?) C’était un moyen glorifié d’accéder aux variables globales. Ils avaient aussi des constructeurs statiques (!), Ce qui est presque toujours une mauvaise idée. (Je sais qu'il y a quelques exceptions raisonnables).

Cependant, les méthodes statiques sont très utiles lorsqu'elles factorisent une logique de domaine qui ne dépend pas réellement de l'état d'une instance de l'objet. Ils peuvent rendre votre code beaucoup plus lisible.

Assurez-vous simplement de les mettre au bon endroit. Les méthodes statiques manipulent-elles de manière intrusive l'état interne d'autres objets? Peut-on affirmer que leur comportement appartient plutôt à l'une de ces classes? Si vous ne séparez pas correctement les problèmes, vous pourriez avoir des maux de tête plus tard.

21
JasonTrue

C'est intéressant à lire:

http://thecuttingledge.com/?p=57

ReSharper ne vous suggère pas réellement de rendre votre méthode statique. Vous devriez vous demander pourquoi cette méthode est dans cette classe par opposition à l'une des classes qui apparaît dans sa signature ...

mais voici ce que dit la documentation de resharper: http://confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static

9
pajics

Juste pour ajouter au @ (Jason) True réponse , il est important de se rendre compte que le simple fait de mettre "statique" sur une méthode ne garantit pas que la méthode sera "pure". Il sera sans état en ce qui concerne la classe dans laquelle il est déclaré, mais il peut très bien accéder à d'autres objets "statiques" ayant un état (configuration de l'application, etc.), ce n'est peut-être pas toujours une mauvaise chose, mais l'une des raisons pour lesquelles Personnellement, j’ai tendance à préférer les méthodes statiques quand je le peux, c’est que si elles sont pures, vous pouvez les tester et les raisonner de manière isolée, sans avoir à vous soucier de l’environnement environnant.

8
Benjol

Pour la logique complexe dans une classe, j'ai trouvé des méthodes statiques privées utiles pour créer une logique isolée, dans lesquelles les entrées d'instance sont clairement définies dans la signature de la méthode et aucun effet secondaire d'instance ne peut se produire. Toutes les sorties doivent être via la valeur de retour ou les paramètres out/ref. Décomposer une logique complexe en blocs de code sans effets secondaires peut améliorer la lisibilité du code et la confiance de l'équipe de développement.

En revanche, cela peut conduire à une classe polluée par une prolifération de méthodes utilitaires. Comme d'habitude, la dénomination logique, la documentation et l'application cohérente des conventions de codage en équipe peuvent remédier à ce problème.

6
G-Wiz

Vous devez faire ce qui est le plus lisible et intuitif dans un scénario donné.

L'argument de performance n'est pas bon, sauf dans les situations les plus extrêmes, car la seule chose qui se passe réellement est qu'un paramètre supplémentaire (this) est poussé sur la pile pour les méthodes d'instance.

6
Eric Schoonover

ReSharper ne vérifie pas la logique. Il vérifie uniquement si la méthode utilise des membres d'instance. Si la méthode est privée et appelée uniquement par (peut-être une seule) méthode d'instance, il s'agit d'un signe permettant de lui attribuer une méthode d'instance.

5
brgerner

Rendre une méthode statique signifie que vous pouvez appeler la méthode de l'extérieur de la classe sans créer au préalable une instance de cette classe. Ceci est utile lorsque vous travaillez avec des objets fournisseurs tiers ou des add-ons. Imaginez si vous deviez d'abord créer un objet console "con" avant d'appeler con.Writeline ();

3
Austin

Si les fonctions sont partagées sur plusieurs pages, vous pouvez également les placer dans une classe de page de base, puis en faire hériter toutes les pages asp.net utilisant cette fonctionnalité (et les fonctions peuvent également être statiques).

3
Mun

Cela aide à contrôler la pollution de l'espace de noms.

2
Josh

Just my tuppence: Ajouter toutes les méthodes statiques partagées à une classe d’utilitaire vous permet d’ajouter

using static className; 

à vos instructions using, ce qui rend le code plus rapide à taper et plus facile à lire. Par exemple, j'ai un grand nombre de ce que l'on pourrait appeler des "variables globales" dans un code dont j'ai hérité. Plutôt que de créer des variables globales dans une classe qui était une classe d'instance, je les ai toutes définies comme des propriétés statiques d'une classe globale. Il fait le travail, si mal, et je peux simplement référencer les propriétés par nom parce que l'espace de noms statique est déjà référencé.

Je ne sais pas si c'est une bonne pratique ou non. J'ai tellement de choses à apprendre sur le C 4/5 et un code hérité à refactoriser que j'essaie simplement de laisser les conseils de Roselyn me guider.

Joey

0
Joseph Morgan