c# - Para subrayar o para no subrayar, esa es la pregunta
(13)
Creo que, en general, los campos de nivel de clase son un error en el diseño del lenguaje. Hubiera preferido que las propiedades de C # tuvieran su propio alcance local:
public int Foo
{
private int foo;
get
{
return foo;
}
set
{
foo = value;
}
}
Eso permitiría dejar de usar campos por completo.
La única vez que prefijo un campo privado con un guión bajo es cuando una propiedad requiere un campo de respaldo por separado. Esa también es la única vez que uso campos privados. (Y dado que nunca uso campos protegidos, internos o públicos, es la única vez que uso el período de campos). En lo que a mí respecta, si una variable necesita tener un alcance de clase, es una propiedad de la clase.
¿Hay algún problema con el prefijo de los campos privados con un guión bajo en C # si la versión binaria va a ser consumida por otros lenguajes marco? Por ejemplo, dado que C # distingue entre mayúsculas y minúsculas, puede llamar un campo "foo" y la propiedad pública "Foo" y funciona bien.
¿Esto tendría algún efecto en un lenguaje que no distingue mayúsculas y minúsculas, como VB.NET, por algún problema de conformidad con CLS (u otros) si los nombres solo se pueden distinguir por mayúsculas y minúsculas?
Cuando desee que su ensamblaje sea compatible con CLS, puede usar el atributo CLSCompliant en su archivo de configuración de ensamblado. El compilador se quejará cuando su código contenga cosas que no sean compatibles con cls.
Entonces, cuando tiene 2 propiedades que solo difieren en el caso, el compilador emitirá un error. Por otro lado, cuando tiene un campo privado y una propiedad pública en la misma clase, no habrá problemas.
(Pero también siempre prefijo a mis miembros privados con un guión bajo. También me ayuda a dejar en claro cuando leo mi código que cierta variable es un campo de miembro).
Después de trabajar en un entorno que tenía reglas de estilo muy específicas y sin sentido desde entonces, continué creando mi propio estilo. Este es un tipo que he cambiado mucho. Finalmente, he decidido que los campos privados siempre serán _field, las variables locales nunca lo tendrán _ y estarán en minúsculas, los nombres de las variables para los controles seguirán vagamente la notación húngara, y los parámetros generalmente serán camelCase.
Detesto this.
palabra clave simplemente agrega demasiado ruido de código en mi opinión. Me encanta Resharper eliminar redundante esto. palabra clave.
Actualización de 6 años: estaba analizando las Dictionary<TKey,T>
internas de Dictionary<TKey,T>
para un uso específico de acceso concurrente y leí mal un campo privado para que sea una variable local. Los campos privados definitivamente no deberían ser la misma convención de nomenclatura que las variables locales. Si hubiera habido un guión bajo, hubiera sido increíblemente obvio.
La notación _fieldName para campos privados es tan fácil de romper . Usando esto." la notación es imposible de romper. ¿Cómo romperías la notación _? Observar:
private void MyMethod()
{
int _myInt = 1;
return;
}
Ahí tienes, acabo de violar tu convención de nombres, pero compila. Prefiero tener una convención de nomenclatura que sea a) no húngara yb) explícita. Estoy a favor de eliminar los nombres húngaros y esto califica de alguna manera. En lugar de un tipo de objeto en frente del nombre de la variable, tiene su nivel de acceso.
Contraste esto con Ruby, donde el nombre de la variable @my_number
vincula el nombre al alcance y es irrompible.
editar: Esta respuesta ha resultado negativa. No me importa, se queda.
La recomendación de Style Cop o no, al explorar .NET Framework muestra una gran cantidad de "_" uso para las variables miembro. Independientemente de lo que recomienden los creadores de Style Cop, no es lo que utilizan la mayoría de los empleados de MS. :) Así que me quedaré con el guión bajo. Debido a que personalmente cometo muchos menos errores al usar el guión bajo, entonces esto (ejemplo: usar varName = varName en lugar de this.varName = varName, está realmente atrapado en mí)
Me gusta el guión bajo, porque entonces puedo usar el nombre en minúscula como parámetros de método como este:
public class Person
{
string _firstName;
public MyClass(string firstName)
{
_firstName = firstName;
}
public string FirstName
{
get { return _firstName; }
}
}
Me gusta usar guiones bajos frente a mis campos privados por dos razones. Uno ya se ha mencionado, los campos se destacan de sus propiedades asociadas en el código y en Intellisense. La segunda razón es que puedo usar las mismas convenciones de nomenclatura si estoy codificando en VB o C #.
No hay implicaciones de ningún tipo. Cuando se compila el código, todo lo que es importante para el compilador es el espacio de nombre y la visibilidad del campo / propiedad. Un guion bajo es tan significativo como cualquier otro caracter al nombrar un identificador. El verdadero truco es usar una convención que usted y las personas a su alrededor puedan entender.
No tendrá ningún efecto.
Parte de las recomendaciones para escribir bibliotecas que cumplen con CLS es NO tener dos entidades públicas / protegidas que difieran solo por caso, por ejemplo, NO debe tener
public void foo() {...}
y
public void Foo() {...}
lo que describes no es un problema porque el artículo privado no está disponible para el usuario de la biblioteca
Todavía me gusta usar guiones bajos frente a campos privados por la razón que mencionó Martin, y también porque los campos privados se ordenarán juntos en IntelliSense. Esto es a pesar de la maldad de las anotaciones del prefijo húngaro en general.
Sin embargo, en los últimos tiempos encuentro que usar el prefijo de subrayado para miembros privados está mal visto, aunque no estoy muy seguro de por qué. Tal vez alguien más lo sabe? ¿Es solo el principio del prefijo? ¿O hubo algo relacionado con el cambio de nombre de los tipos genéricos que tienen caracteres de subrayado en ensamblajes compilados o algo así?
Tomado del archivo de Ayuda de Microsoft StyleCop:
TypeName: FieldNamesMustNotBeginWithUnderscore
CheckId: SA1309
Causa: un nombre de campo en C # comienza con un guión bajo.
Descripción de la regla:
Una violación de esta regla ocurre cuando un nombre de campo comienza con un guión bajo.
De forma predeterminada, StyleCop no permite el uso de guiones bajos, m_, etc., para marcar los campos de clases locales, a favor del ''esto''. prefijo. La ventaja de usar ''esto''. es que se aplica por igual a todos los tipos de elementos, incluidos los métodos, propiedades, etc., y no solo a los campos, haciendo que todas las llamadas a los miembros de la clase sean reconocibles al instante, independientemente del editor que se utilice para ver el código. Otra ventaja es que crea una diferenciación rápida y reconocible entre los miembros de la instancia y los miembros estáticos, que no tendrá prefijo.
Si el campo o el nombre de la variable está destinado a coincidir con el nombre de un elemento asociado a Win32 o COM, y por lo tanto necesita comenzar con un guión bajo, coloque el campo o la variable dentro de una clase especial NativeMethods. Una clase NativeMethods es cualquier clase que contenga un nombre que termine en NativeMethods, y está pensada como un marcador de posición para wrappers Win32 o COM. StyleCop ignorará esta infracción si el elemento se coloca dentro de una clase NativeMethods.
Una descripción de regla diferente indica que la práctica preferida además de la anterior es iniciar campos privados con letras minúsculas, y las públicas con letras mayúsculas.
Editar: como seguimiento, la página del proyecto de StyleCop se encuentra aquí: http://code.msdn.microsoft.com/sourceanalysis . Leer a través del archivo de ayuda brinda mucha información sobre por qué sugieren varias reglas estilísticas.
Ya que estamos hablando de un campo privado, no afecta a un usuario de su clase.
Pero recomiendo usar un guión bajo para el campo privado, porque puede hacer que el código sea más fácil de entender, por ejemplo:
private int foo;
public void SetFoo(int foo)
{
// you have to prefix the private field with "this."
this.foo = foo;
// imagine there''s lots of code here,
// so you can''t see the method signature
// when reading the following code, you can''t be sure what foo is
// is it a private field, or a method-argument (or a local variable)??
if (foo == x)
{
..
}
}
En nuestro equipo, siempre usamos un prefijo de subrayado para campos privados. Por lo tanto, al leer algún código, puedo identificar fácilmente los campos privados y distinguirlos de los locales y los argumentos. En cierto modo, el guión bajo se puede ver como una versión abreviada de "esto".
ACTUALIZACIÓN IMPORTANTE (12 de abril de 2016):
Se nos informó que el estándar interno del equipo .NET CoreFX insiste en usar la notación de subrayado sin dar ninguna idea de por qué. Sin embargo, si observamos de cerca la regla n. ° 3, se hace evidente que existe un sistema de prefijos _
, t_
, s_
que sugiere por qué _
fue elegido en primer lugar.
- Usamos
_camelCase
para campos internos y privados y usamos readonly siempre que sea posible. Prefijo campos de instancia con_
, campos estáticos cons_
y campos estáticos de hilo cont_
. Cuando se usa en campos estáticos,readonly
debe venir después destatic
(es decir,static readonly
noreadonly static
).- Nosotros evitamos
this.
a menos que sea absolutamente necesario.
Entonces, si usted es como el equipo de .NET CoreFX que trabaja con un código de nivel del sistema crítico para el rendimiento, multiproceso, se RECOMIENDA ENCARECIDAMENTE que:
- cumplir con sus estándares de codificación y
- usa la notación de subrayado y
- no lea esta respuesta más
De lo contrario, sigue leyendo ...
LA RESPUESTA ORIGINAL:
Primero acuerde sobre lo que estamos hablando. La pregunta es cómo accedemos a los miembros de la instancia desde métodos no estáticos y constructores de una clase / subclases si los modificadores de visibilidad lo permiten.
Indicación de subrayado
- sugiere que use el prefijo "_" en los nombres de campos privados
- también dice que nunca debes usar "esto" a menos que sea absolutamente necesario
Esta notación
- sugiere que siempre use "esto". para acceder a cualquier miembro de instancia
¿Por qué existe esta notación?
Porque así es como tú
- distinguir un parámetro de un campo cuando comparten el mismo nombre
- asegúrese de estar trabajando en el contexto de la instancia actual
Ejemplo
public class Demo
{
private String name;
public Demo(String name) {
this.name = name;
}
}
¿Por qué existe la notación de subrayado?
A algunas personas no les gusta escribir "esto", pero aún necesitan una forma de distinguir un campo y un parámetro, por lo que aceptaron usar "_" delante de un campo
Ejemplo
public class Demo
{
private String _name;
public Demo(String name) {
_name = name;
}
}
Uno puede pensar que es solo cuestión de gusto personal y que ambas maneras son igualmente buenas / malas. Sin embargo, hay ciertos aspectos donde esta notación supera la notación de subrayado:
Claridad
- nombres de trama de notación de subrayado
- esta notación mantiene los nombres intactos
Carga cognitiva
la notación de subrayado es inconsistente, hace que trate los campos de una manera especial, pero no puede usarlo con otros miembros, cada vez que necesita preguntarse si necesita una propiedad o un campo
esta notación es consistente, no tiene que pensar, siempre usa "esto" para referirse a cualquier miembro
ACTUALIZACIÓN: como se señaló, el siguiente no es un punto de ventaja
Mantenimiento
la notación de subrayado requiere que vigiles
_
mientras refactorizas, por ejemplo, convertir un campo en propiedad (eliminar_
) o lo contrario (agregar_
)esta notación no tiene tal problema
Autocompletado
Cuando necesite ver la lista de miembros de la instancia:
- la notación de subrayado no ayuda mucho, ya que al escribir "_", la ventana emergente de autocompletar muestra los campos privados y todos los tipos disponibles de los ensamblados vinculados mezclados con el resto de los miembros de la instancia
- esta notación te da una respuesta clara, al escribir "esto", todo lo que ves es la lista de miembros y nada más
Ambigüedad
A veces debes lidiar con el código sin la ayuda del Intellisense. Por ejemplo, cuando revisa los códigos o busca el código fuente en línea.
la notación de subrayado es ambigua: cuando ve Something.SomethingElse no puede decir si Something es una clase y SomethingElse es su propiedad estática ... o tal vez Something es una propiedad de instancia actual que tiene su propia propiedad de SomethingElse
esto-la notación es clara: cuando ves Algo.AlgoSólo puede significar una clase con una propiedad estática y cuando ves esto.Algo.AlgoSiempre sabes que Algo es miembro y SomethingElse es su propiedad
Métodos de extensión
No puede usar métodos de extensiones en la instancia en sí sin usar "esto".
- la notación de subrayado requiere que no use "esto", sin embargo, con los métodos de extensión debe
- esta notación le ahorra dudas, siempre usa "this", punto.
Soporte de Visual Studio
- la notación de subrayado no tiene un soporte incorporado en Visual Studio
esta notación es compatible con Visual Studio de forma natural:
- http://www.screenr.com/zDCH
- "Esta." Calificación : Prefiera que todos los campos no estáticos utilizados en métodos no estáticos se introduzcan con
this.
Cª#
Recomendaciones oficiales
Hay muchas pautas oficiales que dicen claramente "no uses guiones bajos" especialmente en C #
la notación de subrayado proviene de C ++, donde es una práctica general que ayuda a evitar conflictos de nombres; también se recomienda que VisualBasic.Net resuelva un problema donde un campo "valor" y una propiedad "Valor" en realidad tienen el mismo nombre, porque VisualBasic no distingue entre mayúsculas y minúsculas
esta notación se recomienda para C # mientras que "_" está explícitamente prohibido:
- esta palabra clave en C #
- Directrices de uso de campo : no aplique un prefijo a nombres de campo o nombres de campos estáticos.
- Pautas para nombres: Nombres de miembros de tipo : No use un prefijo para nombres de campo.
- Convención de nomenclatura general : X NO use guiones bajos, guiones ni ningún otro carácter no alfanumérico
- Regla de afirmación de calidad CA1707 : Los identificadores no deben contener guiones bajos
- El uso de guiones bajos no cumple con CLS (para identificadores públicos y protegidos)
- Convenciones internas de nomenclatura de desarrolladores de .NET Framework : No use un prefijo para las variables miembro. Si desea distinguir entre variables locales y miembros, debe usar "this". en C # y "Yo". en VB.NET.