2010-06-28 31 views
111

Es común ver un nombre de variable _var en un campo de clase. ¿Qué significa el guión bajo? ¿Hay alguna referencia para todas estas convenciones especiales de nombres?Convención de nomenclatura: guión bajo en las variables C++ y C#

+1

posible duplicado de [¿Cuáles son las reglas sobre el uso de un guión bajo en un identificador de C++?] (Http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-un-underscore- in-ac-identifier) ​​ –

+0

No estoy de acuerdo, no es un * duplicado exacto *. Las preguntas se relacionan con los subrayados en los nombres de las variables, pero son preguntas completamente diferentes en el contenido real. (Por ejemplo, este pregunta sobre C#) – Smashery

+0

@R Samuel - Eso es un poco exagerado. – ChaosPandion

Respuesta

94

El guión bajo es simplemente una convención; nada mas. Como tal, su uso siempre es algo diferente para cada persona. Así es como los entiendo para los dos idiomas en cuestión:

En C++, un guión bajo generalmente indica una variable de miembro privado.

En C#, suelo ver que se usa solo cuando se define la variable subyacente de miembro privado para una propiedad pública. Otras variables de miembros privados no tendrían un guión bajo. Sin embargo, este uso ha desaparecido en gran parte con el advenimiento de las propiedades automáticas.

Antes:

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

Después:

public string Name { get; set; } 
+11

Excepto para los equipos que quieren que sus propiedades sean inmutables. – ChaosPandion

+8

Los identificadores que comienzan con guiones bajos están reservados para el compilador. El uso de prefijos de subrayado ** puede ** entrar en conflicto con los símbolos del compilador. –

+11

@Thomas Matthews: no en C#. – EMP

-1

Simplemente significa que es un campo miembro en la clase.

0

No hay una convención de nomenclatura única en particular, pero he visto eso para los miembros privados.

2

El estándar de nomenclatura de Microsoft para C# dice que las variables y los parámetros deben usar la forma de camello inferior IE:paramName. La norma también exige que los campos sigan el mismo formulario, pero esto puede llevar a un código poco claro, por lo que muchos equipos piden un prefijo de subrayado para mejorar la claridad IE:_fieldName.

0

Desde mi experiencia (ciertamente limitado), un subrayado indicará que se trata de una variable miembro privada. Como dijo Gollum, esto dependerá del equipo, sin embargo.

0

Uso el _var naming para las variables miembro de mis clases. Hay 2 razones principales que hago:

1) Me ayuda a realizar un seguimiento de las variables de clase y las variables de función locales cuando estoy leyendo mi código más tarde.

2) Ayuda en Intellisense (u otro sistema de finalización de código) cuando estoy buscando una variable de clase. Simplemente conocer el primer carácter es útil para filtrar a través de la lista de variables y métodos disponibles.

+0

Es una molestia en un método más grande confiar en hover intellisense o escanear para ver si una var se define localmente o no . También prefiere "__" para la estática por las mismas razones que menciona, pero actualmente está fuera de su favor. – crokusek

0

A muchas personas les gusta tener campos privados con el prefijo subrayado. Es solo una convención de nombres.

Las convenciones de nombres "oficiales" de C# prescriben nombres simples en minúsculas (sin guiones bajos) para campos privados.

No conozco las convenciones estándar para C++, aunque los guiones bajos se utilizan ampliamente.

-2

Una convención de nomenclatura como esta es útil cuando está leyendo código, particularmente código que no es el suyo. Una fuerte convención de nomenclatura ayuda a indicar dónde se define un miembro en particular, qué tipo de miembro es, etc. La mayoría de los equipos de desarrollo adoptan una convención de nomenclatura simple, y simplemente prefije los campos de miembro con un guión bajo (_fieldName). En el pasado, he usado la siguiente convención de nomenclatura para C# (que se basa en las convenciones de Microsoft para el.código NET, que se puede ver con reflector):

instancia de campo: m_fieldName
Campo estático: s_fieldName
público/protegido/miembro interno: PascalCasedName()
miembro Privado: camelCasedName()

Esto ayuda a las personas a comprender la estructura, el uso, la accesibilidad y la ubicación de los miembros al leer código desconocido con mucha rapidez.

+2

En realidad, Microsoft no recomienda el uso de m_, s_ prefijos. * No use un prefijo para nombres de campo. Por ejemplo, no use g_ o s_ para distinguir los campos estáticos de los no estáticos. * http://msdn.microsoft.com/en-us/library/ms229012.aspx – Zied

+1

Como dije, eche un vistazo a su fuente código con Reflector. Te sorprenderá lo mucho que eluden sus propias recomendaciones. ;) Como se mencionó en mi publicación, ayuda a mejorar la legibilidad de su código, y a mi último equipo realmente le gustó la convención de nomenclatura mencionada anteriormente. – jrista

0

Es solo una convención que algunos programadores usan para dejar en claro cuando se manipula un miembro de la clase o algún otro tipo de variable (parámetros, locales para la función, etc.). Otra convención que también se usa ampliamente para las variables miembro está prefijando el nombre con 'm_'.

De todos modos, estas son solo convenciones y no encontrarás una sola fuente para todas ellas. Son una cuestión de estilo y cada equipo de programación, proyecto o empresa tiene el suyo (o incluso no tienen ninguno).

2

Con C#, Microsoft Framework Design Guidelines sugiere no utilizar el carácter de subrayado para miembros públicos. Para miembros privados, los caracteres de subrayado son correctos de usar. De hecho, Jeffrey Richter (a menudo citado en las directrices) usa un m_ por ejemplo y una "s_" para miembros estáticos privados.

Personalmente, uso simplemente _ para marcar a mis miembros privados. "m_" y "s_" bordean la notación húngara que no solo está mal vista en .NET, pero puede ser muy detallado y encuentro que las clases con muchos miembros son difíciles de hacer una exploración ocular rápida alfabéticamente (imagine 10 variables todas comenzando con m_) .

+0

Dado que la notación húngara indica el tipo, no creo que realmente puedas decir que m/s está cerca. –

39

En realidad, la convención _var viene de VB no C# o C++ (m _, ... es otra cosa).

Esto llegó a superar la insensibilidad caso de VB cuando se declara Propiedades

por ejemplo, dicho código no es posible en VB, ya que consideran user y User como el mismo 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 

Así que para superar esto, algunos usaron una convención para agregar '_' al campo privado para venir así

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 

Desde hombre Las convenciones son para .Net y para mantener cierta uniformidad entre la convención C# y VB.NET, están usando la misma.

he encontrado la referencia de lo que iba: http://10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices

Caso Camello con subrayado inicial. En VB.NET, siempre indique "Protegido" o "Privado", no use "Dim". El uso de "m_" no es recomendable, como es el uso de un nombre de variable que difiere de la propiedad por único caso, especialmente con las variables protegidas, que viole cumplimiento, y le hará la vida un dolor si programa de VB.NET, como tendría que nombrar a sus miembros algo diferente de las propiedades de acceso/mutador . De todos los artículos aquí, el guión bajo es realmente el único controvertido. Personalmente lo prefiero más caja de camello sin subrayado para mis variables privadas , por lo que no tengo para calificar nombres de variable con "this." para distinguir de los parámetros en constructores o en otro lugar donde I probablemente tendrá una colisión de nombres. Con la insensibilidad de mayúsculas y minúsculas de VB.NET, este es aún más importante ya que sus propiedades de acceso generalmente tendrán con el mismo nombre que las variables de miembro privado excepto el subrayado. En cuanto a m_, realmente es solo sobre estética. Yo (y muchos otros) encuentro m_ feo, ya que parece que hay un agujero en el nombre de la variable. Es casi ofensivo. Solía ​​usarlo en VB6 todo el tiempo, pero eso era solo porque las variables no podían tener un guion bajo principal . No podría estar más feliz de ver que se vaya. Microsoft recomienda en contra de la m_ (y la recta _) a pesar de que ambos hicieron en su código. Además, el prefijo con una "m" recta es correcto. Por supuesto, ya que codifican principalmente en C#, pueden tener miembros privados que difieren solo en el caso de las propiedades. VB amigos tienen que hacer algo más. En lugar de intente encontrar casos especiales de idioma por idioma, I recomendamos el subrayado inicial para en todos los idiomas que lo admitan. Si quiero que mi clase sea completamente CLS-obediente, podría dejar el prefijo en cualquier miembro C12 protegido variables. En la práctica, sin embargo, I nunca se preocupe por esto, ya que guardo todas las variables de miembros potencialmente protegidas privadas, y en su lugar suministre accesos y mutadores protegidos. Por qué: En pocas palabras, esta convención es sencilla (un carácter), fácil de leer (su ojo no es distraído por otros personajes principales), y con éxito evita colisiones de nombres con variables a nivel de procedimiento y de clase Propiedades de nivel. Propiedades de nivel de clase.

4

Puede crear sus propias pautas de codificación. Simplemente escriba una documentación clara para el resto del equipo.

Usar _field ayuda al Intelilsense a filtrar todas las variables de clase simplemente escribiendo _.

Normalmente sigo el Brad Adams Guidelines, pero se recomienda no utilizar el subrayado.

5

El primer comentarista (R Samuel Klatchko) al que se hace referencia: What are the rules about using an underscore in a C++ identifier? que responde a la pregunta sobre el guion bajo en C++. En general, no debe usar un subrayado inicial, ya que está reservado para el implementador de su compilador. El código que está viendo con _var es probablemente un código heredado, o un código escrito por alguien que creció usando el antiguo sistema de nombres que no frunció el ceño al subrayar.

Como otras respuestas afirman, se solía usar en C++ para identificar variables de miembro de clase. Sin embargo, no tiene un significado especial en cuanto a decoradores o sintaxis. Entonces, si quieres usarlo, se compilará.

Dejaré la discusión de C# a los demás.

0

There is a fully legit reason to use it in C#: si el código debe ser extensible desde VB.NET también. (. De lo contrario, no lo haría)

Desde VB.NET es es sensible a mayúsculas, no hay forma sencilla de acceder a la zona protegida field miembros en este código:

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

P. ej esto va a tener acceso a la propiedad de captador, no el campo:

Public Class VBClass 
    Inherits CSharpClass 

    Function Test() As Integer 
     Return Field 
    End Function 

End Class 

Heck, ni siquiera puedo escribir en minúsculas field - VS 2010 sólo mantiene su corrección.

Con el fin de hacer que sea fácilmente accesible para las clases derivadas en VB.NET, uno tiene que encontrar otra convención de nomenclatura. Prefijar un guión bajo es probablemente el menos intrusivo y el más "históricamente aceptado" de ellos.

1

En lo que respecta a los idiomas C y C++, no hay un significado especial para un guión bajo en el nombre (comienzo, medio o final). Es solo un nombre de variable válido. Las "convenciones" provienen de prácticas de codificación dentro de una comunidad de codificación.

Como ya se indicó por varios ejemplos anteriores, _ al principio puede significar miembros privados o protegidos de una clase en C++.

Permítanme darles un poco de historia que puede ser divertida. En UNIX si tiene una función de biblioteca de núcleo C y un backend de kernel donde desea exponer la función de kernel al espacio de usuario, _ está atascada delante del resguardo de función que llama directamente a la función kernel sin hacer nada más. El ejemplo más famoso y familiar de esto es exit() vs _exit() bajo kernels BSD y SysV: allí, exit() hace cosas de espacio de usuario antes de llamar al servicio de salida del kernel, mientras que _exit solo asigna al servicio de salida del kernel.

So _ se usó para cosas "locales" en este caso local siendo machine-local. Por lo general _funciones() no eran portátiles. En eso, no deberías esperar el mismo comportamiento en varias plataformas.

Ahora en cuanto a _ en los nombres de variables, tales como

int _foo;

Bueno psicológicamente, una _ es una cosa extraña de tener que escribir al principio. Por lo tanto, si desea crear un nombre de variable que tenga una menor posibilidad de un choque con otra cosa, ESPECIALMENTE cuando se trata de sustituciones de preprocesador, debe considerar el uso de _.

Mi consejo básico sería seguir siempre las convenciones de su comunidad de codificación, para que pueda colaborar de manera más efectiva.

0

Ahora la notación que usa "this" como en this.foobarbaz es aceptable para las variables miembro de la clase C#. Reemplaza la antigua notación "m_" o solo "__". Hace que el código sea más legible porque no hay duda de lo que se está haciendo referencia.

4

_var no tiene sentido y solo sirve para facilitar la distinción de que la variable es una variable de miembro privado.

En C++, el uso de la convención _var es incorrecto, porque existen reglas que rigen el uso del guión bajo delante de un identificador. _var está reservado como un identificador global, mientras que _Var (guión bajo + letra mayúscula) está reservado en cualquier momento. Es por eso que en C++, verá personas que usan la convención var_ en su lugar.

52

¡NO utilice UNDERSCORES antes de cualquier nombre de variable o nombre de parámetro en C++!

Los nombres que comiencen con un guión bajo o un guión bajo doble están RESERVADOS para los implementadores de C++. Los nombres con un guión bajo están reservados para que la biblioteca funcione.

Si usted tiene una lectura en el C++ estándar de codificación, se verá que en la primera página dice:

"Haz de nombres no overlegislate, pero hace uso de una convención de nomenclatura coherente: Hay solo dos deberes: a) nunca use "nombres clandestinos", que comiencen con un guión bajo o que contengan un guion bajo doble "; (p2, C++ Estándares de codificación, Herb Sutter y Andrei Alexandrescu)

Además, puede verlo usted mismo por qué dicho uso de guiones bajos puede ser desastroso al desarrollar un software.

tratar de compilar un programa helloWorld.cpp simple como esto:

g++ -E helloWorld.cpp 

Va a ver todo lo que sucede en el fondo. Aquí hay un fragmento:

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; 
    } 

¡Puede ver cuántos nombres comienzan con doble guion bajo!

Además, si observa las funciones de miembros virtuales, verá que * _vptr es el puntero generado para la tabla virtual que se crea automáticamente cuando utiliza una o más funciones de miembros virtuales en su clase. Pero esa es otra historia ...

Si usa guiones bajos, es posible que tenga problemas de conflicto y NO TENDRÁ NINGUNA IDEA lo que lo está causando, hasta que sea demasiado tarde.

+2

¿No son los nombres que no son globales o el alcance del archivo y comienzan con guión bajo y una letra minúscula perfectamente bien? Hago esto todo el tiempo porque es muy limpio para casos específicos, por ejemplo, void A :: set_size (int _size) {size = _size; }. ¿Qué haces para usos triviales como este? – tukra

+0

@tukra: No aconsejaría eso. Si el estándar C++ dice, no usar nombres precedidos por un guión bajo o doble guión bajo, entonces eso es lo que todos deberíamos seguir. Si realmente quieres un guión bajo, entonces * supongo * puedes colocarlo al final o entre el nombre, es decir, tamaño_ (aunque eres un "hick-up" lejos de presionar -t- y terminar con el tipo estándar * size_t *). El problema es que simplemente ** no sabes ** cuándo dispararás algo no intencionado. Además, hay otras palabras clave fuera del estándar de C++ que activan el manejo especial del compilador -> https://en.wikipedia.org/wiki/Restrict –

+2

El subrayado seguido de una letra minúscula está permitido en el ámbito no global/del archivo, creo . ¿Puedes mostrarme en el estándar que dice que no es así? El problema con el guión bajo final es que ya lo uso para miembros vars a veces.Entonces podría tener la función 'int size();' miembro var 'int size_;' y argumento 'int _size'. Esto tiende a cubrir las cosas muy bien y no he visto mejores alternativas. Los funcs capitalizados no son posibles para los genéricos que funcionan con STL. El estilo 'this.size' que les gusta a las personas C# parece propenso a errores, a menos que siempre lo utilices para acceder a los miembros, lo cual es desagradable. – tukra

Cuestiones relacionadas