C # - Pourquoi les préfixes sur les champs sont-ils découragés?

À l'époque, nous utilisions la notation hongroise. Cela est maintenant considéré comme passé , et la plupart du temps, je ne l'utilise plus, mais je trouve toujours une utilisation pour le préfixe m _ pour indiquer les champs membres.

Pour moi, si je lis le code de quelqu'un d'autre, je vois ceci:

count = 3;

Je suppose que count est une variable locale de cette fonction et que je fais quelque chose qui sera utilisé ailleurs dans la fonction; si je vois ceci:

m_count = 3;

Je réalise immédiatement que je mets à jour l'état de l'objet.

Les directives de style Microsoft disent que ce n'est pas la bonne façon de faire les choses. Je suis censé nommer mes champs non publics exactement comme des variables temporaires définies dans la fonction. Pas de m _ , pas même un simple trait de soulignement.

Oui, nous pouvons définir notre propre style de codage, mais je dois ensuite lutter contre divers outils d'analyse de code statique, afin de les convaincre que notre façon de faire les choses est correcte.

Je suis heureux de passer au style Microsoft, mais j'aimerais bien savoir pourquoi les choses sont comme ça.

Pourquoi est-il maintenant considéré comme mauvais de pouvoir dire si une variable est une fonction locale ou un membre?

P.S. This is very similar to What is the regarded current best practises regarding the “this” keyword in front of field and methods in c#?, but I'm asking about m_ not this.

P.P.S. Also see Why did Microsoft make parameters, local variables and private fields have the same name naming convention?

14
C # n'a-t-il pas le this mot-clé? Ne pourriez-vous pas faire référence aux membres utilisant this , tel que this.count ?
ajouté l'auteur FrustratedWithFormsDesigner, source
FWIW cette réponse en double question plaide en faveur du préfixe "m_" du point de vue des utilisateurs d'IDE, "comme Dès que vous tapez le petit m , intellisense vous donne la liste de toutes vos variables privées ... "
ajouté l'auteur gnat, source
Pourquoi devez-vous vous souvenir de quelque chose? L'EDI fait cela en survolant la variable.
ajouté l'auteur Andy, source
Si vous imprimez du code en 2017, vous faites quelque chose de mal. Dans les deux autres scénarios, il devrait être assez évident que count n'apparaisse pas hors de nulle part puisqu'il n'a pas été déclaré dans la méthode. Franchement, l'argument "out of IDE" est vraiment faible. D'autant qu'il existe même des outils de révision de code qui fonctionnent dans l'IDE.
ajouté l'auteur Andy, source
Un dernier commentaire; Que vous soyez d'accord avec les recommandations de MS ou non, c'est ce à quoi les développeurs s'attendent dans le monde .Net. La réponse peut donc être au moins une cohérence et une "convivialité" avec la communauté. Tout comme je suivrais les conventions Java si je développais le développement Java.
ajouté l'auteur Andy, source
@gnat Oh merci, je vais signaler la fermeture de cette question également, car elle repose principalement sur l'opinion.
ajouté l'auteur Andy, source
Pouvez-vous lier les directives susmentionnées? Je pense que toutes les directives publiées par Microsoft concernant la convention de nommage des champs privés sont obsolètes (telles que Règles de conception pour les développeurs de bibliothèques de classes et Règles de codage interne ) et les directives en vigueur ( Directives de conception de framework ) ne couvrent pas les champs privés.
ajouté l'auteur Joel, source
La première question que je voudrais poser à propos d'un code comme celui-ci est la suivante: la variable count n'a pas de nom véritablement descriptif. S'il en avait un, le manuel utilise des éléments tels qu'un préfixe m _ qui devient sans objet.
ajouté l'auteur James Snell, source
Le préfixe m_ est un C ++ - ism où il évite les conflits de noms entre champs et méthodes. En C#, ce n'est pas un problème car les noms de méthodes doivent commencer par des majuscules, les champs par des minuscules.
ajouté l'auteur amon, source
Vous devriez utiliser "ceci". avec tous les membres de la classe toujours au lieu de tout autre préfixe arbitraire. C’est pour cela et c’est sans ambiguïté. StyleCop vous aidera à ne pas oublier.
ajouté l'auteur Martin Maat, source
article de Joel toujours pertinent.
ajouté l'auteur François-Olivier Guay, source
@BettyCrokker si ce n'est pas local, il devrait commencer par majuscule, si c'est privé, il devrait commencer par un trait de soulignement. Ce que vous dites (distinguer entre le compte (local) et le compte (membre) est de votre faute, car les membres ne doivent pas être en minuscule. La dénomination est importante. Si vous nommez 3 variables de la même manière, elles ne sont pas assez descriptives
ajouté l'auteur EpicKip, source
@ KaseySpeakman Lecture très intéressante. Cela semble être un argument en faveur de l’utilisation de la notation "gentille" en hongrois, alors que ce qui est montré ci-dessus est la notation "type" en hongrois. Qu'est-ce que "m_" ajoute que l'EDI ne vous dit pas? Considérant que "s" et "nous" de l'article est une méta-information non disponible dans le code. C'est là que c'est utile. Personnellement, je créerais toujours un type réel, mais pour les types simples, il serait peut-être plus utile d'utiliser une convention de dénomination.
ajouté l'auteur Der Zauberer von Oz, source
il devrait être _count , pas m_count
ajouté l'auteur TheCatWhisperer, source
En C#, les préfixes sont totalement inutiles . Cela dit, je préfère vraiment nommer sans préfixe car cela évite les bruits inutiles. Si le même nom est utilisé, alors le seul endroit où vous avez explicitement besoin de this. serait dans un constructeur lorsqu'il existe un mappage un à un entre un paramètre et un membre. Dans un tel cas, puisque les deux font référence à la même chose, avoir des noms distincts est inutile. Dans les fonctions, j'utiliserais toujours un nom différent si une variable locale ou un paramètre aurait le même nom qu'un membre. Cela rend le code plus lisible (par exemple newX pour un paramètre qui met à jour x ).
ajouté l'auteur Phil1970, source
@ TimothyTruckle - pouvez-vous expliquer davantage? La seule raison pour laquelle j’ai vu pourquoi je n’ai pas utilisé le préfixe et que je ne comprends pas ... ce qui n'est pas la même chose que pourquoi je ne devrais pas)
ajouté l'auteur user3487243, source
@KevinFee Même réponse que précédemment - je ne regarde peut-être pas le code à l'intérieur de l'EDI. Et j'ajouterai ceci - même si je suis dans l'IDE, il est agréable de pouvoir comprendre le code sans avoir à passer la souris au-dessus de tout.
ajouté l'auteur user3487243, source
@Andy - oui mais ... il existe de nombreuses situations dans lesquelles je cherche du code en dehors de l'EDI. Exemples - (1) outils de fusion. (2) outils de révision de code. (3) impressions (halètement).
ajouté l'auteur user3487243, source
@TheCatWhisperer - sez qui? Ou, pour être moins désinvolte, donnez une preuve concrète de la raison pour laquelle "" est préférable à "m ".
ajouté l'auteur user3487243, source
Oui, mais (1) c'est plus taper, et (2) c'est facile à oublier. Si le champ s'appelle m_count, je n'ai pas besoin de me rappeler de taper this.m_count
ajouté l'auteur user3487243, source
Microsoft crée de nouvelles directives de dénomination, puis ne les observe pas. Il suffit de regarder la source de référence pour le cadre. Pour moi, une sorte de préfixe (bien que je n'aime pas m _ ) est un bon moyen de voir immédiatement la portée d'une variable (et oui, je préfère une fonction courte où cela ne devrait pas être nécessaire, mais J'ai des collègues ...). Le survol de la souris est un effort supplémentaire.
ajouté l'auteur Boris Nikolov, source
Le préfixe "membre" est une sorte de détail d'implémentation . Cela détourne votre attention du domaine problème au domaine solution technique , qui biaise votre esprit lorsque vous songez à une refactorisation possible.
ajouté l'auteur Adam, source

8 Réponses

C # n'a pas de variables globales, ce qui ne laisse que des variables locales et des champs de classe.

Et si vous avez autant de variables locales que vous perdez la raison de savoir si un identifiant est un identifiant, vous avez certainement violé l'une des instructions permettant de gérer la complexité de la manière la plus grave.

Essayez d’extraire un objet-paramètre, d’essayer de scinder votre fonction en plusieurs fonctions plus simples. Vous devez certainement refactoriser votre code, sauf si vous préférez vous noyer dans les détails et la complexité, sans vous soucier de la maintenabilité.

Maintenant que nous avons établi que l'objectif des décorations "ceci-est-un-membre" n'est plus valable, car la portée de la fonction doit être trop petite et la portée globale n'existe pas, il existe un inconvénient à ces marqueurs: ils empêchent déplacer les arguments/variables locales vers les membres, ou l'inverse.

15
ajouté
@jrh: Eh bien, c'est un cas évident d'échec pour utiliser un nom approprié pour le champ. Je suis sûr qu'il y en a pour ce cas rare (comme vous l'avez dit). En outre, il y a pire que la garantie d'un accident, du moins c'est assez évident.
ajouté l'auteur Shizam, source
@ FrankHileman: Eh bien, comment appelleriez-vous associer un préfixe aléatoire à un nom descriptif approprié, si ce n'est pas loufoque? La décoration semble… inadéquate, d'autant plus que l'addition ne sert plus à rien et que, comme d'autres l'ont dit, cela peut faire obstacle à la refactorisation.
ajouté l'auteur Shizam, source
@ FrankHileman En fait, c'est le cas. Cela explique pourquoi il n'y a pas de bonne raison pour narguer un nom.
ajouté l'auteur Shizam, source
@jrh Eh bien, alors cela semble être une exception pour les propriétés qui ont besoin d'un champ de support juste comme cela pourrait avoir un sens. Tout accès depuis l'extérieur de la propriété évitera probablement le champ de sauvegarde. Concernant votre deuxième exemple, si vous avez besoin de construire quelque chose pour le renvoyer, un nom mécaniste pour le temporaire semble le plus approprié, comme result .
ajouté l'auteur Shizam, source
Une fois que vous y parvenez, cela pourrait également être une classe ou un espace de noms.
ajouté l'auteur user8669, source
"uglifying"? Si tel est le cas, il s'agit d'une question d'opinion seulement. Tout le monde peut avoir une opinion différente sur la laideur. Il y a des raisons de préférer une convention à une autre, mais il n'y a pas de convention standard dans ce cas.
ajouté l'auteur Frank Hileman, source
Cela ne semble pas lié à la question.
ajouté l'auteur Frank Hileman, source
@ La beauté du déduplicateur est dans l'œil du spectateur. Conventions jadis considérées comme laides, j’apprécie maintenant comme utiles.
ajouté l'auteur Frank Hileman, source
Il existe d'autres cas où les préfixes sont utiles, par exemple, le fait de ne pas utiliser de préfixe pour les champs membres signifie que les propriétés qui ont besoin d'un champ de sauvegarde (et ne peuvent pas être transformées en propriétés automatiques) sont toujours une erreur de casse d'un StackOverflowException , intellisense n’aide pas vraiment à cela et va volontiers compléter quelque chose en Quelque chose dans le getter/setter de Quelque chose . Etant donné que cela provoque un crash instantané et ne génère aucun avertissement du compilateur (ne serait capturé que par des tests unitaires ou des tests manuels), j'estime qu'un préfixe est une solution de contournement juste.
ajouté l'auteur jrh, source
En outre, dans un getter qui construit, modifie et renvoie des propriétés, il existe un nombre limité de noms utiles que vous pouvez choisir pour cette variable locale que vous renvoyez qui sont uniques à partir du nom de la propriété.
ajouté l'auteur jrh, source
@DuDuplicator Pour utiliser un exemple aléatoire, supposons que la classe ait une propriété appelée Nom que la classe voulait valider pour voir si le nom donné n'était pas une chaîne vide, null, etc. - vous auriez avoir un champ de sauvegarde nom pour stocker le nom validé, pour autant que je sache, il n'y a aucun moyen d'utiliser des propriétés automatiques pour cela. Je pourrais appeler le champ de base validatedName ou internalName , mais est-ce vraiment mieux qu'un _ ?
ajouté l'auteur jrh, source
Je ne pense pas que cela réponde vraiment à la question.
ajouté l'auteur Vladimir Stokic, source

Quand ils travaillaient sur l’API pour Windows, Microsoft recommandait l’utilisation de la notation hongroise, en utilisant «m_», ainsi que «i», «sz», etc. À l’époque, cela était utile car l’EDI n’était pas robuste. assez pour vous montrer cette information.

C #, d’autre part, a d’emblée un IDE très robuste.

Ils ont donc fait la recommandation dans Consignes de dénomination de Microsoft pour C# pour les champs statiques ou protégés publics:

✓ DO use PascalCasing in field names.
✓ DO name fields using a noun, noun phrase, or adjective.
X DO NOT use a prefix for field names.

Maintenant que vous pouvez la survoler avec votre souris ou que vous appuyez sur CTRL + K + W et obtenir toutes les informations sur le membre, Microsoft est parvenu à la conclusion que les préfixes sont de mauvaise forme. ils constituent une solution manuelle à un problème déjà résolu.

Les champs privés sont spécifiquement exclus des directives, mais Microsoft semble en être venu à la conclusion que c'est le cas même pour les champs privés qui vont de l'avant en interne, ce que vous pouvez voir si vous pointez Resharper vers .NET 4.5 ou .NET Core.

Utilisez vos outils, ne le faites pas manuellement.

12
ajouté
@BettyCrokker Parce que m_ n'ajoute absolument aucune valeur. L'EDI vous dit membre ou non, donc le m_ est redondant. Tout pourquoi vous êtes obsédé par m_? Pourquoi pas l_ (pour les locaux)? Pourquoi pas afsdfjdskfjas_? Je vais inverser la question, car de toute façon, c'est un argument religieux stupide. Fais ce que tu veux. Les instructions que vous appliquez indiquent également "Les instructions de dénomination des champs s'appliquent aux champs publics et protégés statiques . Les champs internes et privés sont _not _ couverts par des directives , et les champs d'instance publics ou protégés ne sont pas autorisés par les directives de conception des membres. "
ajouté l'auteur Andy, source
@BettyCrokker le trait de soulignement principal est en effet une norme non officielle. Vous le verrez dans de nombreuses nombreuses bases de code C #.
ajouté l'auteur RubberDuck, source
@KevinFee Il n'y a pas de directive de conception .net pour les préfixes de champs privés. Les lignes directrices sont pour les membres du public seulement.
ajouté l'auteur Frank Hileman, source
Cette réponse est trompeuse et incorrecte.
ajouté l'auteur Frank Hileman, source
@BettyCrokker Le préfixe de soulignement regroupe les champs privés dans les listes déroulantes classées par ordre alphabétique des membres fournies dans l'EDI. Ils vont toujours en haut de la liste.
ajouté l'auteur Frank Hileman, source
@FrankHileman Mise à jour pour le signaler. Je ne l'ai pas fait car il semblait que les autres réponses le couvraient. Toute autre déclaration incorrecte ou trompeuse?
ajouté l'auteur Der Zauberer von Oz, source
@BettyCrokker Je ne peux trouver aucune justification de la part de JetBrains expliquant pourquoi Resharper le fait par défaut. J'utilise à peine des champs privés, j'utilise presque toujours des propriétés get-only ou private-set. Vous pouvez le configurer pour qu'il préfère plutôt "this." Ou "m_" si vous le souhaitez vraiment, mais c'était bien sûr une des choses que vous n'aimiez pas faire.
ajouté l'auteur Der Zauberer von Oz, source
@FrankHileman Ou vous pouvez utiliser le champ "afficher uniquement les champs" dans intellisense ...
ajouté l'auteur Der Zauberer von Oz, source
@FrankHileman Care pour fournir des informations supplémentaires sur ce qui est incorrect et trompeur? Le simple fait de dire que cela ne m'aide pas à l'améliorer.
ajouté l'auteur Der Zauberer von Oz, source
@BettyCrokker OK, mais vous vous interrogez sur les lignes directrices établies avec cette hypothèse. Vous vous plaignez également des outils statiques qui utilisent probablement cette hypothèse, car "personne" (avec une marge d'erreur statistique acceptable) n'imprime son code C #. Je ne sais pas quels outils d'analyse statistique vous utilisez, mais Resharper est assez spécifique: les champs privés sont "_lowerCase". Les membres publics de tout type ou "UpperCase", et les sections locales sont "lowerCase". Économiser sur le "m" est en fait assez joli, en tout cas.
ajouté l'auteur Der Zauberer von Oz, source
@BettyCrokker Vous demandez pourquoi l'autorité a pris la décision qu'elle a prise. J'explique que c'est parce que leur IDE fait ce que vous voulez sans avoir besoin de le faire manuellement. En quoi le fait de montrer les directives de l'autorité, puis de les expliquer, constitue-t-il un appel à l'autorité?
ajouté l'auteur Der Zauberer von Oz, source
Andy a posté littéralement le même instant que moi. J'ai vu le "1 nouveau commentaire" apparaître lorsque j'ai cliqué sur "ajouter une réponse". En ce qui concerne ces outils, deux d’entre eux sont déjà dans l’EDI. Les impressions ... pourquoi tu fais ça?
ajouté l'auteur Der Zauberer von Oz, source
@KevinFee Si un préfixe est utilisé pour IntelliSense, alors this. peut être utilisé. Son avantage est que vous pouvez le supprimer par la suite et obtenir un code propre et magnifique sans bruit supplémentaire.
ajouté l'auteur Phil1970, source
@ KevinFee C’est intéressant de voir que Resharper utilise le préfixe de soulignement - d’où vient-il? Est-ce juste quelque chose que beaucoup de gens font? J'ai commencé à regarder des outils d'analyse de code statique, si le trait de soulignement est un standard (même un non officiel) qui satisferait mon désir de pouvoir distinguer les variables locales des champs privés ...
ajouté l'auteur user3487243, source
Si vous partez du principe que tout doit être fait à l'intérieur de l'EDI (et que je comprends que Microsoft pousse ce point de vue, cela aide leur entreprise), alors votre conclusion est logique. Pour moi, je ne peux pas faire cette hypothèse.
ajouté l'auteur user3487243, source
Cela ajoute de la valeur pour moi; cela ne vous apportera peut-être pas une valeur ajoutée, et c'est bien, vous n'avez donc pas à l'utiliser. En bout de ligne: m_ ajoute de la valeur pour moi et je n'ai vu aucune raison technique pour laquelle cela fait mal. Merci de signaler le "non couvert par les lignes directrices", cela aide.
ajouté l'auteur user3487243, source
Ma question initiale reste sans réponse ... Oui, Microsoft a dit de ne pas utiliser m_ et les fabricants d'outils l'ont suivi, mais ce n'est pas une raison technique pour utiliser m_, c'est ce qu'on appelle souvent "faire appel à l'autorité". La seule raison technique que je connaisse pour ne pas utiliser m_ vient de Timothy Truckle et je ne le comprends pas ...
ajouté l'auteur user3487243, source
Même réponse à Andy ... oui mais ... il y a beaucoup de situations où je regarde du code en dehors de l'IDE. Exemples - (1) outils de fusion. (2) outils de révision de code. (3) impressions (halètement).
ajouté l'auteur user3487243, source

Pourquoi les développeurs évitent-ils de faire précéder les espaces de noms avec la directive using namespace?

System.DateTime() is much more explicit than DateTime(). It tells me exactly what I'm dealing with. Is it just because we're lazy typists?

Non, nous sommes des dactylographes paresseux, mais ce n'est pas pour ça.

Nous préférons les styles de codage qui nous permettent d’ignorer les détails et de nous concentrer sur les abstractions. Forcer les noms à communiquer les détails de la structure est une source de distraction. Lorsque je travaille sur un algorithme compliqué, je ne veux pas de noms qui insistent pour me rappeler chaque détail de la chose sur laquelle je travaille. J'ai juste besoin du nom pour ne pas confondre Minuteur et DateTime . Je m'inquiéterai si ceux-ci sont compatibles ailleurs.

C'est la même raison pour laquelle vous ne voulez pas que deux gars de votre équipe s'appellent Jon. Le fait qu'ils aient un nom de famille n'est pas une raison pour leur donner des préfixes ou des suffixes. Je vais juste t'appeler Skeet. Quoi de plus est une douleur à plat.

10
ajouté
Les conventions ne font que faciliter le travail avec le code de différents développeurs. Votre réponse concerne l'hongrois, mais il n'y a pas de convention pour les champs privés. La question repose donc sur une hypothèse fausse.
ajouté l'auteur Frank Hileman, source
Cela ne semble pas répondre à la question. Il n'y a pas de préférence générale ou de convention pour les champs privés dans .net.
ajouté l'auteur Frank Hileman, source
@FrankHileman En général, nous préférons les bons noms. Les conventions ne créent pas de bons noms. Les conventions créent des noms comme McOhPlease Von StopItAlreadyStine.
ajouté l'auteur candied_orange, source

Il convient de noter que le guide de style MS ne parle que de méthodes et de variables publiques et protégées. C'est-à-dire que les autres développeurs verront s'ils utilisent votre bibliothèque.

L'idée étant que les bibliothèques Microsoft ont une apparence standard pour les développeurs qui les utilisent.

Vous êtes libre d'utiliser le style de votre choix pour vos variables privées ou locales.

Cela dit, les préfixes de variable sont découragés en général pour un certain nombre de raisons

  • Ils peuvent avoir tort et donc être trompeurs
  • Si vous préfixez le type de variable, sa manière de gérer les classes que vous avez créées n'est pas claire.
  • Il existe un certain nombre de conventions et elles ne sont pas toujours d'accord. Ce que vous trouvez utile peut être inutile pour un autre dev
  • Dans le cas de variables membres, vous pouvez utiliser ceci 'ceci.' mot-clé pour indiquer la portée et le respecteur l’appliquera.
6
ajouté
À l'origine, je n'utilisais aucun préfixe pour les champs. Plus tard, j’ai opté pour un seul caractère "_", comme j’en ai vu d’autres car il déplace tous les champs en haut de la liste des membres par ordre alphabétique lorsque vous utilisez les zones de liste déroulantes de l’IDE. L'absence de convention standard peut être gênante lors de la lecture de code écrit par de nombreux développeurs différents.
ajouté l'auteur Frank Hileman, source
@Ewan J'aime toujours "_" mais je n'essaie pas de convaincre qui que ce soit de l'utiliser. Heureusement, .net a de nombreuses conventions qui résolvent beaucoup de conflits de formatage; celui-ci est relativement petit comparé à mes jours C ++.
ajouté l'auteur Frank Hileman, source
beaucoup de personnes utilisent _ mais les choses changent avec le temps, vous constaterez que le code écrit pour «meilleures pratiques» l'année dernière ne correspond pas aux conventions de cette année
ajouté l'auteur Ewan, source
certaines choses sont vérifiées par le compilateur, donc m_count peut ne pas être une variable membre, mais this.count sera toujours
ajouté l'auteur Ewan, source
Au bout d'un moment, vous voyez tellement de styles différents que vous les ignorez. Si vous essayez d'appliquer un style, vous refactorisez constamment tout
ajouté l'auteur Ewan, source
Certaines personnes préfixent ints avec i, les chaînes avec s, etc., mais que préfixes-tu avec MyClass?
ajouté l'auteur Ewan, source
Si vous appliquez «Ils peuvent être faux, et donc trompeurs» dans la plupart des cas, vous découvrez rapidement que vous ne devez pas nommer de variables ou de fonctions - elles peuvent être fausses après tout! Et je suppose que votre deuxième point est censé dire "classes que vous n'avez PAS créées"? Sinon, je ne comprends tout simplement pas… En tout cas, cela commence à donner l’impression qu’un seul préfixe de soulignement pour les champs non publics est une norme non officielle, c’est probablement la direction que nous prendrons.
ajouté l'auteur user3487243, source

Pour moi, si je lis le code de quelqu'un d'autre et que je vois ceci:

  count = 3;
 
     

Je suppose que "compte" est une variable locale de cette fonction et que je fais quelque chose qui sera utilisé ailleurs dans la fonction

Et vous aurez absolument raison si vous lisez un code source qui respecte les conventions de style de C #. Dans un tel code:

this.count = 3;

assigne une valeur à un champ.

count = 3;

assigne une valeur à une variable locale.

Therefore, C#'s style conventions are clear and unambiguous. They force you not to use any prefix simply because you don't need one.

En ce qui concerne le code source pour lequel les auteurs ont décidé d'utiliser leurs conventions personnelles, vous devez demander à eux personnellement pourquoi ils ont choisi de le faire. S'ils n'utilisent pas de préfixes tels que des traits de soulignement et n'utilisent pas non plus this. , cela conduirait non seulement à un code difficile à lire, mais également aux cas où une convention supplémentaire serait nécessaire:

public class Hello
{
    private string greetings;

    public Hello(string greetings)
    {
        greetings = greetings;//Wait, what is that?!
    }
}

C# n'a-t-il pas le mot-clé this? Ne pourriez-vous pas faire référence aux membres utilisant ceci, tels que this.count?

     

Oui, mais (1) c'est plus taper, et (2) c'est facile à oublier. Si le champ s'appelle m_count, je n'ai pas besoin de me rappeler de taper this.m_count

Ici, cependant, vous avez tort.

C'est plus taper lorsque vous écrivez votre code dans le Bloc-notes. Avec un IDE avec complétion automatique ou, mieux, IntelliSense, la comparaison entre this.count et m_count n'est pas aussi évidente. Notez le Shift + - requis pour taper le trait de soulignement.

Quant à «facile à oublier», encore une fois, cela ne concerne que les utilisateurs de Notepad. Non seulement StyleCop et Resharper ne vous laisseront pas oublier de mettre this. si nécessaire, mais après quelques heures de programmation, ajouter this. à l'habitude devient une habitude.

4
ajouté
Je trouve que l'utilisation de this uniquement lorsque vous en avez besoin entraîne une sensation vraiment incohérente et me distrait beaucoup trop souvent. Si vous utilisez this au lieu d'un préfixe, je pense que vous devriez le toujours l'utiliser. Dans ce cas, il devient un préfixe et vous pouvez également utiliser _ .
ajouté l'auteur RubberDuck, source
RubberDuck a raison. "ce." est un préfixe, bien qu’il ait la signification de compilateur.
ajouté l'auteur Frank Hileman, source

Développons un peu.

Il existe 3 styles de préfixes courants, tous rencontrés occasionnellement dans le code c #:

  • m _
  • _
  • ceci.

Such prefixes are commonly used in the private implementation of a class. The Microsoft recommendation is primarily about the exposed parts of a class.

L'utilisation de m _ par rapport à _ réside dans le fait que le préfixe peut être identique dans l'ensemble de votre base de code si vous utilisez C# ainsi que langues où l'utilisation de _ comme préfixe n'est pas autorisée . * L'avantage de m _ par rapport à this. est qu'il est plus court et que vous n'oublierez pas accidentellement le préfixe.

L'avantage de _ sur m _ est qu'il est plus court et que tout ce qui commence par le préfixe est trié en haut est trié alphabétiquement par un outil. L'avantage de _ sur this. est qu'il est plus court et que vous n'oublierez pas le préfixe par inadvertance.

L’avantage de this. par rapport à m _ et _ est que vous pouvez l’utiliser dans une base de code où _ ou < code> m _ ne sont pas une convention acceptée et universelle. Cela signifie également que personne n'a besoin de connaître la convention _ ou m _ , ce qui peut être perçu comme simplifiant les choses. Inconvénient, étant donné que le compilateur ne se préoccupe pas de ce préfixe, le préfixe this. manquera parfois, et en tant que tel, ne sera pas aussi fiable qu'un indicateur.


*Once you start accessing C# classes that use _ from C++/CLI (which really really shouldn't use _), you'll notice that agreeing on a common prefix is more complex than it should be. Deciding to not have a prefix gets rid of that noise. Combine this with Deduplicator's answer, which I'll paraphrase as "the advantage of a prefix is almost negligible", and it gives us: "There's a tiny problem when using prefixes, and a tiny upside, thus it's a valid choice to just not use them".


Il existe une question plus ancienne sur stackoverflow qui y est liée.

4
ajouté
Belle comparaison. Cependant, je trouve que ne pas utiliser de préfixe fonctionne bien dans la pratique.
ajouté l'auteur Phil1970, source
    

Le préfixe "membre" est une sorte de détail d'implémentation. Cela détourne votre attention du domaine du problème vers le domaine de la solution technique, qui biaise votre esprit lorsque vous songez à des refactorings possibles. - moi

  
     

pouvez-vous expliquer plus loin? C'est la seule raison pour laquelle j'ai compris pourquoi je n'utilisais pas le préfixe et que je ne comprends pas ... (j'entends par là que les autres choses que les gens disent sont des raisons pour lesquelles je n'ai pas à l'utiliser, ce qui n’est pas la même chose que pourquoi je ne devrais pas le faire) - Betty Crokker

Mon point est d'étendre les réponses de @CandiedOrange et @Ewan.

Les préfixes rendent le refactoring plus difficile

À mesure que votre code évolue, les variables et les méthodes peuvent changer de domaine. Par exemple. vous pouvez créer une méthode privée et découvrir plus tard qu'elle devrait également être disponible pour d'autres classes (nouvelles). De même, il peut arriver aux paramètres de la méthode et aux variables locales.

Let's say you create a Tax calculator. According to the principle of lease visibility scope for variables you start with a method that takes both, the tax rate and the base value as parameters:
(example may look Java-ish...)

class TaxCalculator{
   double Calculate(double p_TaxRateInpercent, double p_BaseValue){
     return (100+p_TaxRateInpercent)/100 * p_BaseValue;
   }
} 

Ensuite, vous devez implémenter l'opération inverse et, selon TDD, vous le faites avec le moins d'effort possible:

class TaxCalculator{
   double Calculate(double p_TaxRateInpercent, double p_BaseValue){
     return (100+p_TaxRateInpercent)/100 * p_BaseValue;
   }
   double CalculateBase(double p_TaxRateInpercent, double p_TaxedValue){
     return p_TaxedValue/((100+p_TaxRateInpercent)/100);
   }
} 

Next TDD vous demande de refactoriser le code pour le rendre plus propre, ce qui réduira la liste de paramètres des deux méthodes.
(Oui, vous extrayez d’abord le calcul en double, mais laissez-moi comprendre ce que je veux dire ...)
La solution évidente consiste à modifier le taux d’imposition en une variable membre en le transmettant en tant que paramètre constructeur.

class TaxCalculator{
   double m_TaxRateInpercent;
   TaxCalculator(double p_TaxRateInpercent){
     m_TaxRateInpercent = p_TaxRateInpercent;
   }
   double Calculate(double p_BaseValue){
     return (100+m_TaxRateInpercent)/100 * p_BaseValue;
   }
   double CalculateBase(double p_TaxedValue){
     return p_TaxedValue/((100+m_TaxRateInpercent)/100);
   }
} 

Comme vous pouvez le constater, nous avons dû modifier toutes les lignes de nos méthodes existantes (toutes les lignes utilisées p_TaxRateInpercent pour être exact).

The problem is, that you have no support from your IDE to do the renaming throughout the class. The only help it search/replace which will also change the constructor or any part that accidentally contains the string p_TaxRateInpercent.
You IDE might offer a change to ... refactoring for undefined variable names but this may be restricted to the scope of the method

Sans le préfixe, seules les signatures de méthode auraient changé. Aucun changement de nom n'aurait été nécessaire.


Les préfixes encombrent l’historique SCM lorsqu’ils sont modifiés

De même, le SCM enregistre le changement de préfixe en tant que changement dans la logique, bien que la logique ne change pas! L’histoire de SCM est encombrée de ce changement technique qui cache ce qui est important et augmente le risque de conflits avec les changements (de la logique réelle) des autres.

4
ajouté

J'utilise le préfixe _ pour toutes les variables membres. Je déteste «ce» préfixe parce que, même si certains prétendent que c'est la bonne façon de faire les choses, cela ajoute beaucoup de bruit/fouillis à votre code. Un simple trait de soulignement est également une pratique courante dans les exemples de Microsoft.

Donc, dans votre exemple, j'aurais:

int _count = 10;
2
ajouté