É comum ver um _var
nome de variável em um campo de classe. O que significa o sublinhado? Existe uma referência para todas essas convenções de nomenclatura especiais?
É comum ver um _var
nome de variável em um campo de classe. O que significa o sublinhado? Existe uma referência para todas essas convenções de nomenclatura especiais?
Respostas:
O sublinhado é simplesmente uma convenção; nada mais. Como tal, seu uso é sempre um pouco diferente para cada pessoa. Veja como eu os entendo para os dois idiomas em questão:
No C ++, um sublinhado geralmente indica uma variável de membro particular.
Em C #, normalmente vejo isso usado apenas ao definir a variável de membro privado subjacente para uma propriedade pública. Outras variáveis de membro privado não teriam um sublinhado. Esse uso foi largamente esquecido com o advento das propriedades automáticas.
Antes:
private string _name;
public string Name
{
get { return this._name; }
set { this._name = value; }
}
Depois de:
public string Name { get; set; }
public string Name { get; private set; }
. É verdade que não é perfeitamente imutável, mas está lá.
_var
não está reservado.
É uma prática recomendada NÃO usar UNDERSCORES antes de qualquer nome de variável ou parâmetro em C ++
Nomes começando com um sublinhado ou um sublinhado duplo são RESERVADOS para os implementadores de C ++. Os nomes com sublinhado são reservados para a biblioteca funcionar.
Se você tiver uma leitura no C ++ Coding Standard, verá que na primeira página diz:
"Não exagere na nomeação em excesso, mas use uma convenção de nomenclatura consistente: existem apenas dois itens obrigatórios: a) nunca use" nomes ocultos ", aqueles que começam com um sublinhado ou que contêm um sublinhado duplo;" (p2, padrões de codificação C ++, Herb Sutter e Andrei Alexandrescu)
Mais especificamente, o rascunho de trabalho da ISO indica as regras reais:
Além disso, alguns identificadores são reservados para uso em implementações de C ++ e não devem ser usados de outra forma; nenhum diagnóstico é necessário. (a) Cada identificador que contém um sublinhado duplo __ ou começa com um sublinhado seguido por uma letra maiúscula é reservado à implementação para qualquer uso. (b) Cada identificador que começa com um sublinhado é reservado à implementação para uso como um nome no espaço para nome global.
É uma prática recomendada evitar o início de um símbolo com um sublinhado, caso você acidentalmente vagueie por uma das limitações acima.
Você pode ver por si mesmo por que esse uso de sublinhados pode ser desastroso ao desenvolver um software:
Tente compilar um programa helloWorld.cpp simples como este:
g++ -E helloWorld.cpp
Você verá tudo o que acontece em segundo plano. Aqui está um trecho:
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;
}
Você pode ver quantos nomes começam com um sublinhado duplo!
Além disso, se você observar as funções membro virtuais, verá que * _vptr é o ponteiro gerado para a tabela virtual que é criada automaticamente quando você usa uma ou mais funções membro virtuais em sua classe! Mas isso é outra história ...
Se você usar sublinhados, poderá entrar em problemas de conflito e não terá idéia do que está causando isso, até que seja tarde demais.
Na verdade, a _var
convenção vem do VB e não do C # ou C ++ (m _, ... é outra coisa).
Isso veio para superar a insensibilidade do VB ao declarar Propriedades.
Por exemplo, esse código não é possível no VB porque considera user
e User
como o mesmo identificador
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
Então, para superar isso, alguns usaram uma convenção para adicionar '_' ao campo privado e assim
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
Como muitas convenções são para .Net e para manter alguma uniformidade entre as convenções C # e VB.NET, elas estão usando a mesma.
Encontrei a referência para o que estava dizendo: http://10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices
Camel Case com sublinhado principal. No VB.NET, sempre indique "Protegido" ou "Privado", não use "Dim". O uso de "m_" é desencorajado, assim como o uso de um nome de variável que difere da propriedade apenas por caso, especialmente com variáveis protegidas, pois isso viola a conformidade e tornará sua vida uma dor se você programar no VB.NET, como você teria que nomear seus membros como algo diferente das propriedades de acessador / mutador. De todos os itens aqui, o principal sublinhado é realmente o único controverso. Pessoalmente, prefiro isso ao invés de um caso de camelo sem sublinhado direto para minhas variáveis privadas, para que eu não precise qualificar nomes de variáveis com "isto". para distinguir dos parâmetros em construtores ou em outros lugares onde provavelmente terei uma colisão de nomes. Com a distinção entre maiúsculas e minúsculas do VB.NET, isso é ainda mais importante, pois suas propriedades de acessador geralmente terão o mesmo nome que suas variáveis de membro privadas, exceto o sublinhado. No que diz respeito a m_, é realmente apenas estética. Eu (e muitos outros) acho feio, pois parece que há um buraco no nome da variável. É quase ofensivo. Eu costumava usá-lo no VB6 o tempo todo, mas isso era apenas porque as variáveis não podiam ter um sublinhado à esquerda. Eu não poderia estar mais feliz em vê-lo desaparecer. A Microsoft recomenda contra o m_ (e o _ direto), embora eles tenham feito os dois no código. Além disso, o prefixo com um "m" reto está correto. Obviamente, como codificam principalmente em C #, eles podem ter membros particulares que diferem apenas no caso das propriedades. O pessoal da VB precisa fazer outra coisa. Em vez de tentar criar casos especiais de idioma por idioma, recomendo o sublinhado principal para todos os idiomas que o suportam. Se eu quiser que minha classe seja totalmente compatível com CLS, poderia deixar de fora o prefixo em qualquer variável de membro protegida por C #. Na prática, no entanto, nunca me preocupo com isso, pois mantenho todas as variáveis de membro potencialmente protegidas privadas e forneço acessores e mutadores protegidos. Por que: Em poucas palavras, esta convenção é simples (um caractere), fácil de ler (seu olho não se distrai com outros caracteres principais) e evita com êxito colisões de nomes com variáveis no nível do procedimento e propriedades no nível da classe. . Eu recomendo o sublinhado principal para todos os idiomas que o suportam. Se eu quiser que minha classe seja totalmente compatível com CLS, poderia deixar de fora o prefixo em qualquer variável de membro protegida por C #. Na prática, no entanto, nunca me preocupo com isso, pois mantenho todas as variáveis de membro potencialmente protegidas privadas e forneço acessores e mutadores protegidos. Por que: Em poucas palavras, esta convenção é simples (um caractere), fácil de ler (seu olho não se distrai com outros caracteres principais) e evita com êxito colisões de nomes com variáveis no nível do procedimento e propriedades no nível da classe. . Eu recomendo o sublinhado principal para todos os idiomas que o suportam. Se eu quiser que minha classe seja totalmente compatível com CLS, posso deixar o prefixo em qualquer variável de membro protegida por C #. Na prática, no entanto, nunca me preocupo com isso, pois mantenho todas as variáveis de membro potencialmente protegidas privadas e forneço acessores e mutadores protegidos. Por que: Em poucas palavras, esta convenção é simples (um caractere), fácil de ler (seu olho não se distrai com outros caracteres principais) e evita com êxito colisões de nomes com variáveis no nível do procedimento e propriedades no nível da classe. . Eu nunca me preocupo com isso, pois mantenho todas as variáveis de membro potencialmente protegidas privadas e, ao invés disso, forneço acessores e mutadores protegidos. Por que: Em poucas palavras, esta convenção é simples (um caractere), fácil de ler (seu olho não se distrai com outros caracteres principais) e evita com êxito colisões de nomes com variáveis no nível do procedimento e propriedades no nível da classe. . Eu nunca me preocupo com isso, pois mantenho todas as variáveis de membro potencialmente protegidas privadas e, ao invés disso, forneço acessores e mutadores protegidos. Por que: Em poucas palavras, esta convenção é simples (um caractere), fácil de ler (seu olho não se distrai com outros caracteres principais) e evita com êxito colisões de nomes com variáveis no nível do procedimento e propriedades no nível da classe. .
O primeiro comentarista (R Samuel Klatchko) referenciou: Quais são as regras sobre o uso de sublinhado em um identificador C ++? que responde à pergunta sobre o sublinhado em C ++. Em geral, você não deve usar um sublinhado à esquerda, pois ele é reservado para o implementador do seu compilador. O código com o qual você está vendo _var
provavelmente é um código herdado ou escrito por alguém que cresceu usando o antigo sistema de nomes que não desaprovava os sublinhados principais.
Como outras respostas indicam, ele costumava ser usado em C ++ para identificar variáveis de membros da classe. No entanto, não tem significado especial no que diz respeito aos decoradores ou sintaxe. Então, se você quiser usá-lo, ele será compilado.
Vou deixar a discussão em C # para outras pessoas.
_var não tem significado e serve apenas para facilitar a distinção de que a variável é uma variável de membro privado.
No C ++, o uso da convenção _var é uma forma incorreta, porque existem regras que regem o uso do sublinhado na frente de um identificador. _var é reservado como um identificador global, enquanto _Var (sublinhado + letra maiúscula) é reservado a qualquer momento. É por isso que em C ++, você verá pessoas usando a convenção var_.
Você pode criar suas próprias diretrizes de codificação. Basta escrever uma documentação clara para o resto da equipe.
Usar _field ajuda o Intelilsense a filtrar todas as variáveis de classe apenas digitando _.
Eu geralmente sigo as Diretrizes de Brad Adams , mas recomenda não usar sublinhado.
O padrão de nomeação Microsoft para C # diz variáveis e parâmetros devem usar o formulário caso camelo menor IE: paramName
. A norma também exige campos a seguir a mesma forma, mas isso pode levar a código claro tantas equipes pedir um prefixo sublinhado para melhorar a clareza IE: _fieldName
.
Com o C #, as Diretrizes de Design do Microsoft Framework sugerem não usar o caractere sublinhado para membros públicos . Para membros privados , sublinhados podem ser usados. De fato, Jeffrey Richter (frequentemente citado nas diretrizes) usa um m_ por exemplo e um "s_" para membros estáticos privados.
Pessoalmente, uso apenas _ para marcar meus membros particulares. "m_" e "s_" se aproximam da notação húngara, que não é apenas desaprovada no .NET, mas pode ser bastante detalhada e acho que aulas com muitos membros são difíceis de fazer uma rápida verificação alfabética dos olhos (imagine 10 variáveis, todas começando com m_) .
Eu uso a nomeação _var para variáveis de membro de minhas classes. Existem 2 razões principais que eu faço:
1) Isso me ajuda a acompanhar as variáveis de classe e as funções locais quando leio meu código mais tarde.
2) Ajuda no Intellisense (ou outro sistema de conclusão de código) quando estou procurando uma variável de classe. Apenas conhecer o primeiro caractere é útil para filtrar a lista de variáveis e métodos disponíveis.
No que diz respeito às linguagens C e C ++, não há significado especial para um sublinhado no nome (início, meio ou fim). É apenas um caractere de nome de variável válido. As "convenções" vêm de práticas de codificação dentro de uma comunidade de codificação.
Como já indicado por vários exemplos acima, _ no início pode significar membros privados ou protegidos de uma classe em C ++.
Deixe-me contar uma história que pode ser divertida. No UNIX, se você possui uma função principal da biblioteca C e um back-end do kernel em que deseja expor a função do kernel ao espaço do usuário, o _ fica preso na frente do stub da função que chama a função do kernel diretamente sem fazer mais nada. O exemplo mais famoso e familiar disso é exit () vs _exit () nos kernels do tipo BSD e SysV: Lá, exit () faz coisas no espaço do usuário antes de chamar o serviço de saída do kernel, enquanto _exit apenas mapeia para o serviço de saída do kernel.
Então _ foi usado para coisas "locais", neste caso local sendo local da máquina. Normalmente _functions () não eram portáteis. Nesse sentido, você não deve esperar o mesmo comportamento em várias plataformas.
Agora, como _ nos nomes de variáveis, como
int _foo;
Bem, psicologicamente, um _ é uma coisa estranha a ser digitada no começo. Portanto, se você deseja criar um nome de variável que tenha menos chances de entrar em conflito com outra coisa, ESPECIALMENTE ao lidar com substituições de pré-processador, você deve considerar o uso de _.
Meu conselho básico seria seguir sempre a convenção da sua comunidade de codificação, para que você possa colaborar com mais eficiência.
Muitas pessoas gostam de ter campos particulares com um sublinhado. É apenas uma convenção de nomenclatura.
As convenções de nomenclatura 'oficiais' do C # prescrevem nomes minúsculos simples (sem sublinhado) para campos particulares.
Não conheço as convenções padrão para C ++, embora os sublinhados sejam amplamente utilizados.
É apenas uma convenção que alguns programadores usam para deixar claro quando você está manipulando um membro da classe ou algum outro tipo de variável (parâmetros, local para a função, etc.). Outra convenção que também é amplamente utilizada para variáveis-membro é prefixar o nome com 'm_'.
De qualquer forma, essas são apenas convenções e você não encontrará uma única fonte para todas elas. Eles são uma questão de estilo e cada equipe, projeto ou empresa de programação tem o seu (ou até não o tem).
Há uma razão totalmente legítima para usá-lo em C #: se o código também deve ser extensível a partir do VB.NET. (Caso contrário, eu não faria.)
Como o VB.NET não diferencia maiúsculas de minúsculas, não há uma maneira simples de acessar o field
membro protegido neste código:
public class CSharpClass
{
protected int field;
public int Field { get { return field; } }
}
Por exemplo, isso acessará o getter de propriedades, não o campo:
Public Class VBClass
Inherits CSharpClass
Function Test() As Integer
Return Field
End Function
End Class
Caramba, eu nem consigo escrever field
em letras minúsculas - o VS 2010 continua corrigindo isso.
Para torná-lo facilmente acessível para classes derivadas no VB.NET, é necessário criar outra convenção de nomenclatura. Prefixar um sublinhado é provavelmente o menos intrusivo e o mais "historicamente aceito" deles.
Pergunta antiga, nova resposta (C #).
Outro uso de sublinhados para C # é o DI (injeção de dependência) do ASP NET Core. readonly
Variáveis privadas de uma classe que foram atribuídas à interface injetada durante a construção devem começar com um sublinhado. Eu acho que é um debate se usar sublinhado para todos os membros privados de uma classe (embora a própria Microsoft o siga), mas este é certo.
private readonly ILogger<MyDependency> _logger;
public MyDependency(ILogger<MyDependency> logger)
{
_logger = logger;
}
Uma convenção de nomenclatura como essa é útil quando você está lendo um código, principalmente um código que não é seu. Uma convenção de nomenclatura forte ajuda a indicar onde um membro específico é definido, que tipo de membro é etc. A maioria das equipes de desenvolvimento adota uma convenção de nomenclatura simples e simplesmente prefixa os campos dos membros com um sublinhado ( _fieldName
). No passado, eu usei a seguinte convenção de nomenclatura para C # (que é baseada nas convenções da Microsofts para o código de estrutura .NET, que pode ser visto no Reflector):
Campo da instância: m_fieldName
Campo estático: s_fieldName Membro
público / protegido / interno: PascalCasedName ()
Membro privado: camelCasedName ()
Isso ajuda as pessoas a entender a estrutura, o uso, a acessibilidade e a localização dos membros ao ler códigos desconhecidos muito rapidamente.