web-dev-qa-db-fra.com

Convention de dénomination - trait de soulignement dans les variables C++ et C #

Il est courant de voir un nom de variable _var dans un champ de classe. Qu'est-ce que le trait de soulignement? Existe-t-il une référence pour toutes ces conventions de dénomination spéciales?

121
Stan

Le soulignement est simplement une convention; rien de plus. En tant que tel, son utilisation est toujours quelque peu différente pour chaque personne. Voici comment je les comprends pour les deux langues en question:

En C++, un trait de soulignement indique généralement une variable membre privée.

En C #, je le vois généralement utilisé uniquement lors de la définition de la variable de membre privé sous-jacente pour une propriété publique. Les autres variables membres privés n'auraient pas de trait de soulignement. Cet usage a largement échoué avec l'avènement des propriétés automatiques.

Avant:

private string _name;
public string Name
{
    get { return this._name; }
    set { this._name = value; }
}

Après:

public string Name { get; set; }
100
jdmichal

S'il vous plaît NE PAS utiliser UNDERSCORES avant tout nom de variable ou nom de paramètre en C++ !!!

Les noms commençant par un trait de soulignement ou un double soulignement sont réservés pour les implémenteurs C++. Les noms avec un trait de soulignement sont réservés au fonctionnement de la bibliothèque.

Si vous avez lu au standard de codage C++, vous verrez que dans la toute première page, il est écrit:

"Ne réglez pas trop les noms, mais utilisez une convention de nommage cohérente: il n'y a que deux choses à faire: a) n'utilisez jamais de" noms sombres ", ceux qui commencent par un trait de soulignement ou qui contiennent un double soulignement; (p2, Normes de codage C++, Herb Sutter et Andrei Alexandrescu)

En outre, vous pouvez voir vous-même pourquoi une telle utilisation des traits de soulignement peut être désastreuse lors du développement d'un logiciel.

Essayez de compiler un programme simple helloWorld.cpp comme ceci:

g++ -E helloWorld.cpp

Vous verrez tout ce qui se passe en arrière-plan. Voici un extrait:

   ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
   try
     {
       __streambuf_type* __sb = this->rdbuf();
       if (__sb)
  {
    if (__sb->pubsync() == -1)
      __err |= ios_base::badbit;
    else
      __ret = 0;
  }

Vous pouvez voir combien de noms commencent par un double soulignement!

De même, si vous examinez les fonctions de membre virtuelles, vous verrez que * _vptr est le pointeur généré pour la table virtuelle qui est automatiquement créée lorsque vous utilisez une ou plusieurs fonctions de membre virtuelles dans votre classe! Mais c'est une autre histoire ...

Si vous utilisez des traits de soulignement, vous risquez de rencontrer des problèmes de conflit et vous n'aurez pas IDEA ce qui le cause, jusqu'à ce qu'il soit trop tard.

59
Constantinos Glynos

En réalité, la convention _var provient de VB et non de C # ou C++ (m _, ... est une autre chose).

Cela permettait de surmonter l'insensibilité à la casse de VB lors de la déclaration de propriétés.

par exemple, un tel code n'est pas possible dans VB car il considère que user et User sont identiques.

Private user As String

Public Property User As String
  Get
    Return user
  End Get
  Set(ByVal Value As String)
    user = value
  End Set
End Property

Donc, pour surmonter cela, certains ont utilisé une convention pour ajouter '_' au domaine privé à venir comme ceci

Private _user As String

Public Property User As String
  Get
    Return _user
  End Get
  Set(ByVal Value As String)
    _user = value
  End Set
End Property

Comme beaucoup de conventions sont pour .Net et pour garder une certaine uniformité entre les conventions C # et VB.NET, elles utilisent la même.

J'ai trouvé la référence pour ce que je disais: http://10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices

Affaire Camel avec Underscore de premier plan. Dans VB.NET, indiquez toujours "Protected" ou "Privé", n'utilisez pas "Dim". Utilisation de "m_" est déconseillé, de même que l'utilisation d'un nom de variable qui diffère de propriété par cas seulement, en particulier avec variables protégées car cela viole conformité, et fera de votre vie un douleur si vous programmez en VB.NET, comme vous devrait nommer vos membres quelque chose de différent du propriétés accesseur/mutateur. De tout les éléments ici, le soulignement principal est vraiment le seul sujet à controverse . Personnellement, je préfère le droit étui de chameau sans soulignement pour mon variables privées afin que je n'ai pas qualifier les noms de variables avec "this." distinguer des paramètres dans constructeurs ou ailleurs où je probablement aura une collision de nommer . Avec l'insensibilité à la casse de VB.NET, this est d'autant plus important que votre les propriétés des accesseurs auront généralement le même nom que votre membre privé variables sauf le trait de soulignement . En ce qui concerne m_, c’est vraiment juste sur l'esthétique. Moi (et beaucoup d'autres) trouvez m_ laid, comme on dirait là-bas est un trou dans le nom de la variable. Ses presque offensant. Je l'utilisais auparavant VB6 tout le temps, mais c'était seulement parce que les variables ne peuvent pas avoir un trait de soulignement. Je ne pouvais pas être. plus heureux de le voir partir. Microsoft recommande contre le m_ (et le straight _) même s'ils ont fait les deux dans leur code. En outre, préfixer avec un tout droit "m" est juste dehors. Bien sûr, puisqu'ils codent principalement en C #, ils peuvent avoir des membres privés qui diffèrent seulement en cas des propriétés. VB personnes faire autre chose. Plutôt que essayez et venez avec cas particuliers langue par langue, I recommande le trait de soulignement pour toutes les langues qui le supporteront. Si Je veux que ma classe soit pleinement Conforme au CLS, je pourrais laisser le préfixe sur tout membre protégé par C # variables. En pratique, cependant, je ne vous inquiétez jamais de cela car je garde tout variables de membre potentiellement protégées privé et approvisionnement protégé accesseurs et mutateurs à la place. Pourquoi: En un mot, cette convention est simple (un caractère), facile à lire (votre œil n'est pas distrait par les autres personnages principaux .__) et avec succès évite les conflits de nommage avec variables de niveau procédure et propriétés de niveau classe. propriétés de niveau classe.

40
Zied

Le premier commentateur (R Samuel Klatchko) a mentionné: Quelles sont les règles d'utilisation d'un trait de soulignement dans un identifiant C++? qui répond à la question sur le trait de soulignement en C++. En général, vous n'êtes pas censé utiliser un trait de soulignement principal, car il est réservé à l'implémenteur de votre compilateur. Le code que vous voyez avec _var est probablement soit un code hérité, soit un code écrit par quelqu'un qui a grandi en utilisant l'ancien système de nommage et qui ne fronçait pas les sourcils. 

Comme d'autres réponses l'indiquent, il était utilisé auparavant en C++ pour identifier les variables de membre de classe. Cependant, cela n’a aucune signification particulière en ce qui concerne les décorateurs ou la syntaxe. Donc, si vous voulez l'utiliser, il va compiler.

Je laisserai la discussion C # à d'autres.

5
bsruth

_var n'a aucune signification et ne sert qu'à faciliter la distinction entre une variable membre privée et une variable membre privée.

En C++, l'utilisation de la convention _var est une forme incorrecte, car des règles régissent l'utilisation du trait de soulignement devant un identificateur. _var est réservé comme identifiant global, tandis que _Var (trait de soulignement + lettre majuscule) est réservé à tout moment. C'est pourquoi, en C++, vous verrez à la place des utilisateurs de la convention var_.

4
5ound

Vous pouvez créer vos propres directives de codage. Il suffit d'écrire une documentation claire pour le reste de l'équipe.

L'utilisation de _field permet à Intelilsense de filtrer toutes les variables de classe en tapant simplement _.

Je suis généralement les Brad Adams Guidelines , mais il est recommandé de ne pas utiliser de soulignement.

4

La norme de dénomination Microsoft pour C # stipule que les variables et les paramètres doivent utiliser la forme de casse de chameau inférieure IE: paramName. La norme appelle également les champs à suivre le même formulaire, mais cela peut conduire à un code peu clair. Par conséquent, de nombreuses équipes demandent un préfixe de soulignement pour améliorer la clarté IE: _fieldName

2
ChaosPandion

Avec C #, Microsoft Framework Design Guidelines suggère de ne pas utiliser le caractère de soulignement pour les membres public. Pour les membres private, les caractères de soulignement sont acceptables. En fait, Jeffrey Richter (souvent cité dans les directives) utilise un m_ par exemple et un "s_" pour les membres statiques privés. 

Personnellement, je n'utilise que _ pour marquer mes membres privés. "m_" et "s_" s'approchent de la notation hongroise, ce qui est non seulement mal vu dans .NET, mais peut être assez verbeux et je trouve les classes avec beaucoup de membres difficiles à faire un balayage rapide des yeux par ordre alphabétique (imaginez 10 variables commençant par m_) .

2
P.Brian.Mackey

J'utilise le nommage _var pour les variables membres de mes classes. Il y a 2 raisons principales que je fais:

1) Cela me permet de garder une trace des variables de classe et des variables de fonction locales lorsque je lis mon code ultérieurement.

2) Cela aide dans Intellisense (ou tout autre système d’achèvement de code) lorsque je cherche une variable de classe. Il est utile de connaître le premier caractère pour filtrer la liste des variables et méthodes disponibles.

1
A.J.

En ce qui concerne les langages C et C++, il n’ya pas de signification particulière à un trait de soulignement dans le nom (début, milieu ou fin). C'est juste un caractère de nom de variable valide. Les "conventions" proviennent des pratiques de codage au sein d'une communauté de codage.

Comme déjà indiqué dans divers exemples ci-dessus, _ au début peut signifier des membres privés ou protégés d'une classe en C++.

Permettez-moi de vous raconter une histoire qui peut être une anecdote amusante. Sous UNIX, si vous avez une fonction principale de la bibliothèque C et un noyau du noyau où vous souhaitez exposer la fonction du noyau à l'espace utilisateur, le _ est bloqué devant le talon de fonction qui appelle directement la fonction du noyau sans rien faire d'autre. L'exemple le plus connu et le plus connu est exit () vs _exit () sous les noyaux de types BSD et SysV: Là, exit () effectue un travail dans l'espace utilisateur avant d'appeler le service de sortie du noyau, alors que _exit est uniquement mappé sur le service de sortie du noyau.

Donc, _ était utilisé pour des éléments "locaux", dans ce cas local étant local-machine. Les fonctions _ (généralement) n'étaient pas portables. En cela, vous ne devez pas vous attendre au même comportement sur différentes plates-formes.

Maintenant, comme pour _ dans les noms de variables, tels que 

int _foo; 

Bien psychologiquement, un _ est une chose étrange de devoir taper au début. Donc, si vous voulez créer un nom de variable qui aurait moins de chance d’être en conflit avec quelque chose d’autre, surtout lorsqu’il s’agit de substitutions de pré-processeurs, vous devez considérer les utilisations de _.

Mon conseil de base serait de toujours suivre la convention de votre communauté de codage afin de pouvoir collaborer plus efficacement.

1
Elf King

Il y a une raison tout à fait légitime de l'utiliser en C #: si le code doit être extensible à partir de VB.NET également ..__ (sinon, je ne le ferais pas).

VB.NET étant sensible à la casse, il n’existe pas de moyen simple d’accéder au membre field protégé dans ce code:

public class CSharpClass
{
    protected int field;
    public int Field { get { return field; } }
}

Par exemple. ceci accédera au getter de propriété, pas au champ:

Public Class VBClass
    Inherits CSharpClass

    Function Test() As Integer
        Return Field
    End Function

End Class

Zut, je ne peux même pas écrire field en minuscule - VS 2010 ne cesse de le corriger.

Afin de le rendre facilement accessible aux classes dérivées dans VB.NET, il faut trouver une autre convention de dénomination. Préfixer un trait de soulignement est probablement le moins intrusif et le plus "accepté historiquement" d'entre eux.

0
Andras Vass

Il n'y a pas de convention de dénomination unique, mais je l'ai vue pour des députés.

0
Cade Roux

D'après mon expérience (certainement limitée), un trait de soulignement indiquera qu'il s'agit d'une variable membre privée. Comme Gollum l’a dit, cela dépendra de l’équipe.

0
Smashery

Beaucoup de gens aiment avoir des champs privés précédés d'un trait de soulignement. C'est juste une convention de nommage.

Les conventions de nommage "officielles" de C # prescrivent des noms simples en minuscules (pas de soulignement) pour les champs privés.

Je ne connais pas les conventions standard pour C++, bien que les caractères de soulignement soient très largement utilisés.

0
Mau

Il s'agit simplement d'une convention utilisée par certains programmeurs pour indiquer clairement lorsque vous manipulez un membre de la classe ou un autre type de variable (paramètres, locaux à la fonction, etc.). Une autre convention qui est également largement utilisée pour les variables membres est de préfixer le nom avec 'm_'.

Quoi qu'il en soit, ce ne sont que des conventions et vous ne trouverez pas une source unique pour toutes. C’est une question de style et chaque équipe de programmation, projet ou entreprise a le sien (ou n’en a même pas).

0
goedson

La notation utilisant "this" comme dans this.foobarbaz est acceptable pour les variables de membre de classe C #. Il remplace l'ancienne notation "m_" ou simplement "__". Cela rend le code plus lisible car il n’ya aucun doute sur ce qui est référencé.

0
ddm