Pourquoi ne devrais-je pas préfixer mes champs?

Je n’ai jamais été un fan de la notation hongroise, je l’ai toujours trouvé inutile à moins de faire de la programmation à très bas niveau, mais dans tous les projets C ++ sur lesquels j’ai travaillé, avec elle l’utilisation de certains préfixes «pas vraiment hongrois» comme m_ pour les champs, s_ pour les statiques, g_ pour les globaux et ainsi de suite.

Bientôt, j’ai réalisé à quel point c’était inutile en C # et j’ai progressivement abandonné toutes mes vieilles habitudes … mais la chose “m_”. J’utilise toujours le préfixe m_ dans les champs privés car je trouve très utile de pouvoir distinguer les parameters, les sections locales et les champs.

La convention de dénomination des champs de MSDN indique que je ne devrais pas, mais elle ne dit pas pourquoi (comme par exemple les conventions de Google ont tendance à rationaliser leurs prescriptions).

Y a-t-il des raisons pour lesquelles je ne devrais pas ou est-ce seulement une question de style? Si c’est le dernier, les préfixes sont-ils généralement considérés comme un mauvais style et puis-je s’attendre à des réactions négatives de la part de personnes travaillant sur le code?

J’aime le préfixe underbar pour les champs membres. La plupart du temps, cela me plait car de cette manière, tous les champs de mes membres sont affichés par ordre alphabétique avant mes méthodes dans la barre de l’assistant en haut de l’écran.

WizardBar

Quand vous devriez:

  • Lorsque vos directives de codage de projet disent que vous devriez

Quand tu ne devrais pas:

  • Lorsque vos directives de codage de projet disent que vous ne devriez pas

Si vous ne disposez pas encore de directives, vous êtes libre de choisir ce que vous ou votre équipe voulez et vous sentez plus à l’aise. Personnellement, lors du codage de C ++, j’ai tendance à utiliser m_ pour les membres, cela aide. Lors du codage dans d’autres langues, en particulier celles sans vraies classes (comme Javascript, Lua), je ne le fais pas.

En bref, je ne crois pas qu’il y ait une “bonne” et une “mauvaise” manière.

La fonctionnalité de propriété implémentée automatiquement dans C # 3.0 crée moins de besoin pour cette convention dans un sens ou dans l’autre. Au lieu d’écrire

 ssortingng m_name; public ssortingng Name { get { return m_name; } } 

ou

 ssortingng _Name; public ssortingng Name { get { return _Name; } } 

(ou toute autre convention), vous pouvez maintenant écrire

 public ssortingng Name { get; private set; } 

Comme vous n’avez plus besoin de la variable de sauvegarde explicite, vous n’avez plus besoin de lui atsortingbuer un nom; évitant ainsi toute cette discussion.

Évidemment, cet argument ne s’applique pas lorsque vous avez vraiment besoin d’un magasin de sauvegarde explicite, par exemple pour effectuer une validation.

Comme l’ont fait allusion certains, les lignes direcsortingces du MS disent:

N’utilisez pas de préfixe pour les noms de champs. Par exemple, n’utilisez pas g_ ou s_ pour distinguer les champs statiques des champs non statiques.

Je suis d’accord avec cela. les préfixes rendent votre code moche et gaspillent de l’espace avec des caractères sans importance. Cela dit, il est souvent courant d’utiliser des champs pour sauvegarder des propriétés où le champ et la propriété ont le même nom (le champ privé étant le cas camel et la propriété étant le cas pascal). En VB, cela ne fonctionne pas, car VB ne fait pas la distinction entre les majuscules et les minuscules. Dans ce scénario, je recommande l’utilisation d’un seul préfixe. Ni plus ni moins. Il semble juste plus propre, à mon humble avis.

J’ai expérimenté avec m_, s_, juste _ et pas de préfixe du tout. Je me suis contenté d’utiliser simplement _ pour toutes les variables statiques et d’instance. Je ne trouve pas important de distinguer les variables statiques des variables d’instance. En théorie, cela semble bien, dans la pratique, cela ne crée pas de problème.

Un collègue a déjà fait un argument convaincant pour éliminer tous les préfixes, nous l’avons essayé sur un projet et cela a mieux fonctionné que prévu. Je l’ai porté à mon prochain projet et je me suis énervé qu’il “interfère” avec Intellisense. Lorsque vous avez la situation suivante

 int foo; public int Foo { get { return foo; } } 

Commencer à taper foo suggérera à la fois la variable d’instance et la propriété. Préfixer la variable avec un trait de soulignement élimine la double suggestion ennuyeuse, donc je suis revenu à utiliser simplement _.

J’essaie de suivre les directives de la bibliothèque MSDN .NET . Ils comprennent une section de directives de nommage .

Évidemment, ceux-ci sont secondaires aux directives de votre projet.

Je préfère marquer les champs de sauvegarde des propriétés (bien que comme déjà mentionné, NET 3.0+ réduit le besoin grâce aux propriétés automatiques) avec des traits de soulignement mais pas le “m”. Pour l’un, il les place en tête de la liste InteliSense lorsque je les utilise.

J’admets que je dois réviser les directives sur MSDN, les choses peuvent changer si rapidement ces jours-ci.

Avec des outils tels que reharper, il n’y a vraiment aucune raison pour les préfixes. Aussi, si vous écrivez des méthodes courtes, vous devriez être capable de dire très rapidement d’où vient la var. Enfin, je suppose que je ne verrais pas vraiment la nécessité de faire la différence entre un statique ou un non parce que le ré-estomper va le rendre rouge si vous essayez de faire quelque chose que vous ne pouvez pas faire. Même sans réacheminement, vous êtes probablement enregistré par le compilateur.

Je préfixe toujours les variables membres avec m_ et les variables statiques avec s_ pour les mêmes raisons que vous énoncez. Certaines personnes préfixent les variables membres avec un trait de soulignement, mais j’ai toujours trouvé cela un peu bizarre (mais c’est juste une préférence personnelle).

La plupart des personnes avec qui je travaille utilisent le préfixe m_ / s_. Je ne pense pas vraiment que ce que vous utilisez a d’importance, tant que vous êtes cohérent.

Je ne les utilise jamais. Il encourage le codage bâclé. Les directives de codage MSDN, c’est là que ça se passe.

Voici quelques raisons d’utiliser _ (et non m_).

(1) Beaucoup de gars de la BCL le font malgré le guide de nommage de MS. (Consultez leur blog .) Ces gars-là écrivent le framework, ils ont donc de bonnes habitudes à copier. Certains des exemples de code les plus utiles sur MSDN sont écrits par eux et utilisent donc la convention de soulignement. C’est une norme indussortingelle de facto.

(2) Un seul trait de soulignement est un moyen perceptible mais discret de désambiguïser les variables de méthode et de classe en lisant simplement la source. Il aide les gens à comprendre le nouveau (ou l’ancien) code en un coup d’œil lors de sa lecture. Oui, vous pouvez passer la souris pour voir cela dans un IDE, mais nous ne devrions pas être obligés de le faire. Vous voudrez peut-être le lire dans un éditeur de texte ou oser le dire sur papier.

(3) Certains disent que vous n’avez besoin d’aucun préfixe car les méthodes seront courtes, et plus tard si nécessaire, vous pouvez changer le champ en une propriété implémentée automatiquement. Mais dans le monde réel, les méthodes sont aussi longues que nécessaire et il existe des différences importantes entre les champs et les propriétés (par exemple, la sérialisation et l’initialisation).

Note de bas de page: Le “m” pour member in m_ est redondant dans notre utilisation ici, mais il s’agissait de minuscules car l’une des idées de nombreuses anciennes conventions de nommage était que les noms de types commençant par des majuscules et des minuscules. Cela ne s’applique pas à .NET, il est donc redondant. En outre, la notation hongroise était parfois utile avec les anciens compilateurs C (par exemple, la conversion de nombres entiers ou de pointeurs et l’arithmétique), mais même en C ++, son utilité était réduite pour les classes.

Il existe une différence importante entre le support C ++ et C #: Tool. Lorsque vous suivez les directives établies (ou les variantes courantes), vous bénéficiez d’un niveau de prise en charge des outils inégalé par C ++. Suivre les normes permet aux outils d’effectuer des opérations de refactoring / renommer plus en profondeur que ce que vous seriez normalement capable de faire. Resharper fait cela. Tenez-vous donc à l’une des normes établies.

Comme @John Kraft le mentionne, il n’y a pas de réponse “correcte”. MattJ est le plus proche – vous devez toujours suivre les directives de votre entreprise. Quand à Rome et tout ça.

En ce qui concerne mon opinion personnelle, puisque cela est demandé ici, je vote pour que vous m_ tomber m_ entièrement.

Je crois que le meilleur style est celui où tous les membres sont PascalCased , indépendamment de la visibilité (cela signifie même private membres private ), et tous les arguments sont camelCased . Je ne brise pas ce style.

Je peux comprendre le désir de préfixer le champ magasin de sauvegarde de propriété; après tout, vous devez faire la distinction entre le terrain et la propriété, non? Je suis d’accord, vous devez. Mais utilisez un post-correctif.

Au lieu de m_MyProperty (ou même _MyProperty , que j’ai déjà vu et même promu une fois), utilisez MyPropertyValue . Il est plus facile à lire et à comprendre et, plus important encore, il est proche de votre nom de propriété d’origine dans IntelliSense.

En fin de compte, c’est la raison pour laquelle je préfère un postfixe. Si je veux accéder à MyPropertyValue utilisant intellisense, vous tapez (en général) ” My “, car à ce moment-là vous êtes assez proche pour que seules MyProperty et MyPropertyValue figurent dans la liste. Si vous voulez accéder à m_MyProperty utilisant intellisense, vous devrez taper ” m_My “.

C’est à propos de l’économie de frappe, à mon avis.

Je ne le fais jamais et la raison en est que je [essaie] de garder mes méthodes courtes. Si je peux voir toute la méthode à l’écran, je peux voir les parameters, je peux voir les sections locales et je peux donc dire ce qui appartient à la classe et ce qui est un param ou un local.

Je nomme généralement mes parameters et mes sections locales en utilisant une notation particulière, mais pas toujours. Je ne suis rien sinon incohérent. Je compte sur le fait que mes méthodes sont courtes et essaie de les empêcher de faire X, Y et Z alors qu’elles ne devraient faire que X.

En tout cas, c’est mes deux cents.

Sauf si je suis coincé avec vi ou Emacs pour l’édition du code, mon IDE s’occupe de l’affichage différentiel des membres pour moi, donc j’utilise rarement des conventions spéciales. Cela vaut également pour le préfixe des interfaces avec I ou des classes avec C.

Quelqu’un, s’il vous plaît, explique le style .NET du préfixe I sur les interfaces. 🙂

ce à quoi je suis habitué est que les propriétés privées ont un petit trait de soulignement f.ex “ssortingng _name”. le public a eu “Nom”. et les variables d’entrée dans les méthodes ont une petite lettre “void MyMethod (nom de chaîne)”.

si vous avez statique, const est souvent écrit avec de grandes lettres. static const MYCONST = "hmpf" .

Je n’utilise jamais de verrues hongroises chaque fois que j’ai le choix. C’est du typage supplémentaire et ne transmet aucune information significative. Tout bon IDE (et je définis «bon» en fonction de la présence de cette fonctionnalité, entre autres) vous permettra d’avoir une syntaxe différente pour les membres statiques, les membres d’instance, les fonctions membres, les types, etc. code avec des informations pouvant être fournies par l’EDI. Ceci est un corollaire de ne pas encombrer votre code avec l’ancien code commenté, car votre système de gestion des versions devrait être responsable de ce genre de choses.

Le meilleur moyen est de convenir d’une norme avec vos collègues et de vous y tenir. Ce n’est pas forcément la méthode qui conviendrait le mieux à tout le monde, il est plus important de se mettre d’accord sur une méthode que sur la méthode sur laquelle vous êtes réellement d’accord.

Ce que nous avons choisi pour notre code standard est d’utiliser _ comme préfixe pour les variables membres. L’une des raisons est que cela facilite la recherche des variables locales dans le intellisense.

Avant de nous mettre d’accord sur ce standard, j’en ai utilisé un autre. Je n’ai pas utilisé de préfixe du tout et this.memberVariable écrit this.memberVariable dans le code pour montrer que j’utilisais une variable membre.

Avec la propriété raccourci dans C # 3, je trouve que j’utilise beaucoup moins de variables membres explicites.

Je suis sûr que je vais me brûler pour cela mais tant pis.

Cela s’appelle les directives de la bibliothèque .NET de Microsoft mais ce sont vraiment les vues de Brad Adams – il y a d’autres points de vue avec des raisons valables.

Les gens ont tendance à aller dans le sens de la majorité plutôt que d’avoir de bonnes raisons solides pour un style spécifique.

L’important est d’évaluer pourquoi un style spécifique est utilisé et pourquoi il est préférable à un autre style – autrement dit, avoir une raison de choisir un style non seulement parce que tout le monde dit que c’est la chose à faire – penser par vous-même.

La raison de base pour ne pas utiliser l’ancien style hongrois était l’utilisation d’abréviations qui étaient différentes pour chaque équipe et difficiles à apprendre – ceci est facilement résolu en ne abrégeant pas.

Au fur et à mesure que les outils de développement disponibles changent, le style doit évoluer vers ce qui est le plus logique – mais pour chaque élément de style, il existe une raison valable.

Vous trouverez ci-dessous mes directives de style avec mes raisons – Je suis toujours à la recherche de moyens d’améliorer mon style pour créer du code plus fiable et plus facile à gérer.

Convention de dénomination variable

Nous avons tous notre avis sur les conventions de dénomination des variables. Il existe de nombreux styles différents qui aideront à produire un code de qualité facile à gérer – tout style qui prend en charge les informations essentielles sur une variable est correct. Les critères d’une convention de dénomination spécifique devraient être qu’elle aide à produire un code fiable et facile à gérer. Les critères à ne pas utiliser sont les suivants: Microsoft (c’est-à-dire Brad Adams) dit qu’il ne faut pas utiliser ce style – Microsoft ne produit pas toujours le code le plus fiable, il suffit de regarder les bogues dans Expression Blend. Lors de la lecture d’un code, il est très important qu’un nom de variable transmette instantanément trois faits essentiels sur la variable: sa scope, son type et sa compréhension de l’étendue: Microsoft recommande de s’appuyer totalement sur IntelliSense. IntelliSense est génial; Cependant, il ne suffit pas de survoler chaque variable pour voir sa scope et son type. En supposant qu’une variable se trouve dans une scope, cela peut entraîner des erreurs significatives. Par exemple, si une variable de référence est transmise en tant que paramètre et que sa scope locale est modifiée, cette modification restra après le retour de la méthode, ce qui peut ne pas être souhaité. Si un champ ou une variable statique est modifié dans la scope locale mais que l’on pense qu’il s’agit d’une variable locale, un comportement inattendu pourrait en résulter. Par conséquent, il est extrêmement important de pouvoir simplement regarder une variable (et non la souris) et de connaître instantanément sa scope.

Le style suivant pour indiquer la scope est suggéré. Cependant, tout style est parfaitement correct tant qu’il indique clairement et de manière cohérente l’étendue de la variable: m_ champ variable paramètre p_ transmis à une méthode s_ variable statique variable locale Type: des erreurs graves peuvent se produire si l’on pense travailler avec un type spécifique lorsque ils travaillent en fait avec un type différent – encore une fois, nous ne faisons tout simplement pas passer la souris sur une variable pour déterminer son type, nous supposons simplement que nous connaissons son type et que c’est ainsi que les erreurs sont créées.

Abréviations: Les abréviations sont mauvaises car elles peuvent signifier différentes choses pour différents développeurs. Un développeur peut penser qu’une minuscule en tête “s” signifie une chaîne alors qu’un autre peut penser qu’il signifie un entier signé. Les abréviations sont un signe de codage paresseux – prenez un peu de temps supplémentaire et tapez le nom complet pour que le développeur qui doit gérer le code le sache. Par exemple, la différence entre “str” ​​et “ssortingng” n’est que de trois caractères – cela ne demande pas beaucoup plus d’efforts pour rendre le code facile à gérer.

Les abréviations communes et claires pour les types de données intégrés uniquement sont acceptables mais doivent être normalisées au sein de l’équipe.

Code auto-documenté: L’ajout d’une description claire à un nom de variable facilite grandement la lecture et la compréhension du code par un autre développeur – rend le nom si compréhensible que le responsable de l’équipe peut lire et comprendre le code sans être un développeur.

Ordre des parties de nom de variable: L’ordre recommandé est description du type de scope car: IntelliSense regroupera tous les domaines similaires et, à l’intérieur de chaque domaine, IntelliSense regroupera tous les types similaires, facilitant ainsi la recherche. voir et comprendre la scope et voir et comprendre le type C’est un style assez commun et facile à comprendre

Exemples: Voici quelques exemples: m_ssortingngCustomerName p_ssortingngCustomerDatabaseConnectionSsortingng intNumberOfCustomerRecords ou iNumberOfCustomerRecords ou integerNumberOfCustomerRecords Ces règles simples amélioreront considérablement la fiabilité et la maintenabilité du code.

Structure de contrôle Instructions de ligne unique Toutes les structures de contrôle (if, while, for, etc.) peuvent toujours être placées entre accolades car il est très facile d’append une nouvelle instruction sans se rendre compte qu’une instruction donnée appartient à une structure de contrôle qui casser la logique de code sans générer aucune erreur de compilation.

Exclusion de méthode Enveloppement Toutes les méthodes doivent être entourées d’une capture externe qui piège, fournit un endroit pour récupérer, identifier, localiser, enregistrer et décider de lancer ou non. C’est l’exception inattendue qui fait planter nos applications – en encapsulant toutes les méthodes interceptant toutes les exceptions non gérées, nous garantissons l’identification et la journalisation de toutes les exceptions et nous empêchons notre application de tomber en panne. Cela demande un peu plus de travail mais les résultats en valent la peine.

Indentation L’ indentation n’est pas un problème majeur; Cependant, quatre espaces et ne pas utiliser d’tabs sont suggérés. Si le code est imprimé, le premier onglet de l’imprimante est généralement défini par défaut sur 8 espaces. Différents développeurs ont tendance à utiliser différentes tailles d’onglet. Le code de Microsoft est généralement en retrait de 4, donc si vous utilisez un code Microsoft et que vous utilisez d’autres espaces que 4, le code devra être reformaté. Quatre espaces le rendent facile et cohérent.

Je n’utilise plus ce style. Il a été développé pour vous aider à voir rapidement comment les variables étaient utilisées. Les environnements de développement les plus récents vous permettent de voir ces informations en passant votre souris sur la variable. Le besoin en a disparu si vous utilisez ces nouveaux outils.

L’avantage de cette notation en C / C ++ était de faciliter la visualisation du type de symbole sans devoir chercher la déclaration. Ces styles sont apparus avant l’arrivée d’Intellisense et de “Go to Definition” – nous devions souvent aller à la chasse aux oies à la recherche de la déclaration qui sait combien de fichiers d’en-tête. Sur un projet de grande envergure, cela peut être une gêne importante lorsqu’on examine le code source C, mais pire encore lorsqu’on fait de la criminalistique à l’aide de l’assemblage mixte + code source et d’une stack d’appels bruts.

Face à ces réalités, l’utilisation de m_ et de toutes les autres règles hongroises commence à avoir du sens même avec le temps nécessaire à la maintenance en raison du temps économisé en recherchant simplement le type de symbole lorsque l’on regarde un code inconnu. Maintenant, bien sûr, nous avons Intellisense et “Go to Definition”, de sorte que la motivation principale de cette convention de nommage n’est plus là. Je ne pense pas qu’il soit plus utile de le faire, et j’essaie généralement d’utiliser les directives de la bibliothèque .NET simplement pour être cohérent et éventuellement pour gagner un peu plus de support.

Le plus proche des directives officielles est StyleCop , un outil de Microsoft qui peut parsingr automatiquement vos fichiers sources et détecter les violations du style de codage recommandé, et peut être exécuté à partir de Visual Studio et / ou de builds automatisés tels que MSBuild.

Nous l’utilisons sur nos projets et cela aide à rendre le style de code et la mise en page plus cohérents entre les développeurs, même s’il faut savoir que cela prend pas mal de temps pour s’y habituer!

Pour répondre à votre question – il ne permet aucune notation hongroise, ni aucun préfixe comme m_ (en fait, il ne permet pas l’utilisation de caractères de soulignement).

Les normes de codage C ++ ( Sutter, Herb et Alexandrescum Andrei , 2004) pourraient également être utiles. L’article n ° 0 s’intitule “Ne pas transpirer les petites choses. (Ou: Savoir ne pas standardiser.)”.

Ils abordent un peu cette question spécifique en disant: “Si vous ne pouvez pas décider de votre propre convention de nommage, essayez … les variables membres privées telles queThis_ …” ).

Cependant, avant d’y arriver, ils mettent l’accent sur un certain niveau de cohérence “… l’important n’est pas de définir une règle mais juste d’être cohérente avec le style déjà utilisé dans le fichier …”

Si vous ne codez pas sous une directive particulière, vous devriez continuer à utiliser votre notation m_ actuelle et la modifier si les directives de codage du projet le stipulent.

Être fonctionnel

  • N’utilisez pas de variables globales.
  • N’utilisez pas de variables statiques.
  • N’utilisez pas de variables membres.

Si vous devez vraiment le faire, mais seulement si vous devez vraiment le faire, utilisez une et une seule variable pour accéder à votre application / environnement.