Subrayar o no subrayar, esa es la pregunta


131

¿Hay algún problema al no anteponer campos privados con un guión bajo en C # si la versión binaria va a ser consumida por otros lenguajes de framework? Por ejemplo, dado que C # distingue entre mayúsculas y minúsculas, puede llamar a un campo "foo" y a la propiedad pública "Foo", y funciona bien.

¿Tendría algún efecto en un lenguaje que no distinga entre mayúsculas y minúsculas, como VB.NET, por algún problema de cumplimiento de CLS (u otros) si los nombres solo se distinguen por mayúsculas y minúsculas?


18
El punto del prefijo de subrayado, por cierto, no es tratar con problemas de casos. Es poder distinguir fácil y visualmente los campos y los locales al leer el código. Lo usaré en C # y VB por igual.
Neil Hewitt el

2
@NeilHewitt: Bueno, también evita que los parámetros de la función entren en conflicto con las variables miembro, lo que requiere anteponer cada una de ellas this, lo que apesta. EDITAR: acabo de responder a un comentario de cuatro años ...
Ed S.

Solo por claridad, el estándar oficial es _camelCase(solo favorecido) github.com/dotnet/corefx/blob/master/Documentation/…
Chris Marisic

Prefiero _camelCase para tiendas de respaldo privadas. es decir: el archivo privado que contiene los datos asignados y accedidos a través de una propiedad. No me gustan las propiedades automáticas porque no se pueden inicializar a un valor conocido en la definición de clase, y si quiero un efecto secundario en el setter, necesito un almacén de respaldo declarado explícitamente. Desafortunadamente, esto se refactoriza cuando uso ^ R ^ E en el editor de c #, así que tengo que agregarlo nuevamente ... cada vez.
TomXP411

Respuestas:


47

Se tendrá ningún efecto.

Parte de las recomendaciones para escribir bibliotecas compatibles con CLS es NO tener dos entidades públicas / protegidas que difieran solo por caso, por ejemplo, NO debería tener

public void foo() {...}

y

public void Foo() {...}

lo que está describiendo no es un problema porque el elemento privado no está disponible para el usuario de la biblioteca


1
Aunque no tendrá ningún efecto, sigue siendo una convención con la que me sentiría incómodo, ya que es una receta para la confusión si difieren solo según el caso. Es demasiado fácil leer mal o escribir mal si la única diferencia es el capital inicial.
ChrisA

2
PD: Personalmente, no subrayo en C #. Para mí es una preferencia personal, no una creencia religiosa
Binary Worrier

1
He hecho ambas cosas y quería
decidirme

46
Estoy usando guiones bajos. Es más fácil distinguirlos de los argumentos y las variables locales.
Rinat Abdullin el

44
Utilizo _ solo para campos privados, sin embargo, casi nunca tengo campos privados debido a la propiedad automática 3.5. Generalmente, el único momento en que tengo un campo privado es si implemento la carga diferida en tipos no primitivos.
Chris Marisic

279

ACTUALIZACIÓN IMPORTANTE (12 de abril de 2016):

Se nos señaló 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 nos fijamos bien en la regla # 3 se hace evidente que existe un sistema de _, t_, s_prefijos que sugiere por qué _fue elegido en el primer lugar.

  1. Usamos _camelCasepara campos internos y privados y utilizamos solo lectura cuando sea posible. Prefijar campos de instancia con _, campos estáticos con s_y campos estáticos de subprocesos con t_. Cuando se usa en campos estáticos, readonlydebe aparecer después static(es decir, static readonlyno readonly static).
  2. Evitamos a this.menos que sea absolutamente necesario.

Entonces, si usted es como el equipo de .NET CoreFX que trabaja en un código de nivel de sistema crítico, multiproceso y de rendimiento crítico, le SUGERIMOS FUERTEMENTE:

  • adherirse a sus estándares de codificación y
  • use la notación de subrayado y
  • no lea más esta respuesta

De lo contrario, sigue leyendo ...

LA RESPUESTA ORIGINAL:

Primero pongamos de acuerdo de lo que estamos hablando. La pregunta es cómo accedemos a los miembros de la instancia desde métodos y constructores no estáticos de una clase / subclase si los modificadores de visibilidad lo permiten.

Notación de subrayado

  • sugiere que use el prefijo "_" en los nombres de los campos privados
  • también dice que nunca debe usar "esto" a menos que sea absolutamente necesario

Esta notación

  • sugiere que siempre uses "esto". para acceder a cualquier miembro de la 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 acordaron 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 gustos personales y que ambas formas son igualmente buenas / malas. Sin embargo, hay ciertos aspectos en los que esta notación supera a la notación de subrayado:

Claridad

  • nombres de desorden de guiones bajos
  • esta notación mantiene los nombres intactos

Carga cognitiva

  • la notación de subrayado es inconsistente, te hace tratar los campos de una manera especial, pero no puedes usarlo con otros miembros, cada vez que necesites preguntarte si necesitas una propiedad o un campo

  • esta notación es consistente, no tienes que pensar, siempre usas "this" para referirte a cualquier miembro

ACTUALIZACIÓN: como se señaló, lo 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 ese problema

Autocompletado

Cuando necesite ver la lista de miembros de la instancia:

  • la notación de subrayado no le ayuda mucho, porque cuando escribe "_", la ventana emergente de autocompletar le 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 le da una respuesta clara, escribiendo "esto" todo lo que ve es la lista de miembros y nada más

Ambigüedad

A veces tienes que lidiar con el código sin la ayuda de Intellisense. Por ejemplo, cuando realiza revisiones de código o explora 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

  • esta notación es clara: cuando ves Something.SomethingElse solo puede significar una clase con una propiedad estática y cuando ves this.Something.SomethingElse sabes que Something es miembro y SomethingElse es su propiedad

Métodos de extensión

No puede usar métodos de extensiones en la instancia misma sin usar "this".

  • la notación de subrayado requiere que no use "esto", sin embargo, con los métodos de extensión debe
  • esta notación lo salva de dudas, siempre usa "esto", punto.

Soporte de Visual Studio

  • la notación de subrayado no tiene soporte incorporado en Visual Studio
  • Visual Studio admite esta notación de forma natural:

    1. "Esta." Calificación : Prefiera que todos los campos no estáticos utilizados en métodos no estáticos sean precedidos this.en C #

Recomendaciones oficiales

Hay muchas pautas oficiales que dicen claramente "no use guiones bajos", especialmente en C #


22
Esta es una respuesta asombrosa. Gracias por tomarse el tiempo para recopilar toda esta información.
Tigran

55
No proviene de C ++, porque en C ++ reserva los identificadores que comienzan con un guión bajo para el lenguaje y los usos estándar de la biblioteca.
Rob G

77
¿Por qué distingue entre código de nivel de sistema crítico, multiproceso, y otro código? ¿Cómo _camelCaseme va a ayudar el uso si mi código es crítico para el rendimiento / código de nivel de sistema?
BornToCode

66
El uso de guiones bajos no tiene nada que ver con la escritura de código crítico, multihilo o de nivel de sistema. Lo que importa es la coherencia y el equipo CoreFX es solo un equipo que acordó una convención específica. Esta es una gran respuesta, respaldada con un análisis muy agradable que compara las convenciones de nomenclatura, pero creo que la parte adicional que dice "los subrayados son mejores porque el equipo de CoreFX lo dice" realmente disminuye su calidad.
Şafak Gür

55
Mi problema es que entiendo la inferencia lógica. en.wikipedia.org/wiki/Inference Pero bueno, entiendo que no es para todos.
user603563

67

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:

Se produce una violación de esta regla 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 clase locales, a favor de 'this'. 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, lo que hace que todas las llamadas a los miembros de la clase sean reconocibles al instante, independientemente del editor que se esté utilizando 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án prefijo.

Si el nombre del campo o la variable está destinado a coincidir con el nombre de un elemento asociado con 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 de NativeMethods. Una clase NativeMethods es cualquier clase que contiene un nombre que termina en NativeMethods, y está destinada como un marcador de posición para los contenedores Win32 o COM. StyleCop ignorará esta violació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 comenzar campos privados con letras minúsculas y públicos con letras mayúsculas.

Editar: Como seguimiento, la página del proyecto StyleCop se encuentra aquí: https://github.com/DotNetAnalyzers/StyleCopAnalyzers . Leer el archivo de ayuda ofrece una gran comprensión de por qué sugieren varias reglas estilísticas.


77
Es sobre todo un tipo de "mejores prácticas". Como dice la regla, el prefijo con "esto" se puede aplicar a cualquier miembro no estático, mientras que el prefijo con cualquier otra cosa puede no ser aplicable debido a las reglas de sintaxis del lenguaje. La palabra clave "this" hace que el destino previsto sea trivialmente claro.
Scott Dorman el

55
También estoy a favor de la solución del problema al lenguaje ("esto") sobre las formas artificiales de solucionarlo.
galaktor

10
También hay una regla en el mismo software que dice que no debería tener dos campos diferentes solo en caso. Entonces, ¿qué haces con una variable protegida envuelta por una propiedad pública?
Lilith River

55
Mi único problema con la cuestión de 'no subrayar' es que cuando programo contra un formulario (web) o similar, usar solo 'esto' no me ayuda a filtrar a esos campos privados que he definido y en su lugar solo me da Una lista gigantesca de los ocho millones de otras propiedades incluidas con dicho objeto.

14
StyleCop parece estar diciendo que, si uso constantemente thiscuando me refiero a cualquier miembro de la clase, podría encontrar todas las llamadas a todos los miembros de la clase simplemente buscando this. No puedo discutir eso, pero tampoco puedo pensar en un momento en el que necesite hacer eso. Lo último que quiero hacer es agregar tedio a la codificación y ensuciar mi código this(que es casi húngaro) para obtener casi ninguna ganancia práctica. El hecho es que, si estoy mirando una línea de código, cualquier cosa que comience con una letra mayúscula o un guión bajo es un miembro de la clase, cualquier cosa en minúscula es un local.
devuxer

27

Como 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 puede verse como una versión abreviada de "esto".


14
Bueno, siempre prefijo 'esto' sin importar si agrego un campo, propiedad o método.
TheCodeJunkie

9
Para mí, el guión bajo es una especie de notación abreviada de "esto".
M4N

2
En R #, el consejo es no llamar al parámetro foo. ¿Por qué no llamarlo 'valor' ya que sabe que se usará para configurar Foo?
thinkbeforecoding

17
@ Martin: El problema con el guión bajo como una abreviatura de "esto" es que no necesariamente se puede aplicar a todos los miembros de la clase, mientras que "esto" sí. Creo que el código se lee mucho más fácil / más limpio con la palabra clave "this". En su ejemplo, el if (foo == x) siempre se referirá al parámetro foo.
Scott Dorman el

3
@TheCodeJunkie: Eso es un montón de caracteres redundantes en su base de código.
Ed S.

15

Después de trabajar en un entorno que tenía reglas de estilo muy específicas e inútiles desde entonces, creé mi propio estilo. Este es un tipo que he cambiado mucho de un lado a otro. Finalmente he decidido que los campos privados siempre serán _field, las variables locales nunca tendrán _ y serán minúsculas, los nombres de las variables para los controles seguirán libremente la notación húngara, y los parámetros generalmente serán camelCase.

Odio el this. palabra clave, en mi opinión, simplemente agrega demasiado ruido de código. Me encanta Resharper's eliminar esto redundante. palabra clave.

Actualización de 6 años: estaba analizando los aspectos internos de Dictionary<TKey,T>un uso específico de acceso concurrente y leí mal un campo privado como 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, habría sido increíblemente obvio.


18
La thispalabra clave es una referencia garantizada al objeto actual. No obtienes eso con un guión bajo. No hay necesidad de detestar this.
Jason S

15
¿Por qué inventar un 'estándar'? 'esta.' le dice que el objeto es una variable de instancia 'Clase'. te dice que es una variable de clase. Todo lo demás es una variable de pila. El guión bajo pertenece al mismo montón de malas ideas donde la notación húngara ahora se descompone.
Quarkly

44
@ DRAirey1 es demasiado fácil como para perderse esto. cuando lo necesitas y terminas haciendo cosas raras con el estado.
Chris Marisic

3
@ChrisMarisic Por supuesto, usted es bienvenido a su opinión sobre el uso de _, pero no lo considere un estándar establecido cuando claramente no lo es.
aplastar

3
Te perdí en "Fui a crear mi propio estilo".
rory.ap

12

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

39
Nombre de cadena pública {get; conjunto privado; }
jason

3
Todavía puede usar las minúsculas como parámetro del método, usando la thispalabra clave. Haciendo de eso un punto mudo en el continuo y siempre controvertido "subrayar o no":public MyClass(string firstName){ this.firstName = firstName; }
mateuscb

55
Es el futuro, ahora justo public string FirstName { get; }y el setter todavía está disponible en el constructor
Chris Marisic

En este ejemplo. thissolo sería necesario en el constructor. No es necesario usarlo en ningún otro lado. Entonces, firstNamecomo el nombre del campo funciona muy bien.
Thomas Eyde

9

Todavía me gusta mucho usar guiones bajos delante de los campos privados por la razón que Martin mencionó, y también porque los campos privados se ordenarán en IntelliSense. Esto a pesar de la maldad de las anotaciones de prefijos húngaros 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é. Quizás 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 reciben guiones bajos en ensamblajes compilados o algo así?


44
Para mí, el _ abarrota las _ palabras cuando _ escanea rápidamente a través del código, se vuelve menos como leer _y _ más _ como tener que detenerse en _todos _ para reconocerlo y _ darse cuenta de que no es un carácter de control de algún _sort. También interrumpe la sangría al empujar prácticamente el primer carácter útil en los nombres de campo una columna a la derecha. En general, no me gusta C ++ porque la mayoría de los programadores de C ++ tienden a escribir símbolos increíblemente concisos y lentos para leer / códigos similares a máquinas y simplemente prefiero no tener eso en el código C # :)
Oskar Duveborn

23
Para mí, el esto. abarrota las this.words cuando rápidamente this.scanning a través del código, se vuelve menos como leer esto.y this.more this.like tener que parar y this.every this. para reconocerlo y this.realize es this.not un carácter de control de algunos this.sort. Preferiría encontrar lo ocasional _fieldFooo _fieldBartener mi uso abarrotado de this.fieldFooo this.fieldBar. Creo que el this.prefijo es mucho más discordante que un guión bajo destacado.
AggieEric

Estaba pensando que tal vez esta discrepancia en la experiencia podría provenir de los sistemas de archivos de la vieja escuela o los protocolos de transferencia de archivos donde no se permitían espacios que capacitaran a algunos usuarios para ver guiones bajos como espacios y, por lo tanto, no distraer su lectura. Yo, por otro lado, tengo problemas con los nombres de archivo, ya que siempre usé espacios en mis propios nombres de archivo desde el principio ...
Oskar Duveborn

1
@AggieEric golpeó el clavo en la cabeza allí. ¡Solo leer su oración me da dolor de cabeza! Traté de apegarme a la recomendación de la EM durante años en este asunto, y me ENFERZO de leer pequeñas thispalabras azules en todas partes, tomé una decisión de ira nerd allí mismo. Ahora, uso religiosamente thisSOLO para referencias de propiedad, o cuando necesito distinguir explícitamente entre thisy base. Cada uno a lo suyo, supongo :-)
Riegardt Steyn

1
Creo que es porque, en última instancia, comenzar cualquier cosa con un carácter de puntuación perjudica la legibilidad. No parece molestar a todos, pero para mí es muy poco natural leer cualquier cosa que comience con la puntuación. Cuanto más parecido al inglés es el código, más fácil me resulta leerlo. Y con los IDE modernos, es muy sencillo distinguir entre los miembros locales y los miembros privados, porque lo más probable es que sean de diferentes colores.
Tim Long

5

Recomendación de Style Cop o no, profundizar en .NET Framework muestra mucho uso "_" para las variables miembro. Lo que recomiendan los creadores de Style Cop, no es lo que la mayoría de los empleados de MS están usando. :) Así que me quedaré con el guión bajo. Debido a que personalmente cometo muchos menos errores usando el guión bajo y luego el this (ejemplo: usando varName = varName en lugar de this.varName = varName, realmente está atrapado en mí)


3
El subrayado también se recomienda para la guía de estilo principal de .NET: github.com/dotnet/corefx/wiki/Coding-style
landoncz

3

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 ámbito 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 separado. Esa es también la única vez que uso campos privados. (Y como nunca uso campos protegidos, internos o públicos, esa es la única vez que uso el período de campos). En lo que a mí respecta, si una variable necesita tener alcance de clase, es una propiedad de la clase.


La pandilla C # parece estar de acuerdo con usted con el int int foo {get; conjunto;} sintaxis azúcar.
Dana el

Oh, por supuesto; lo que estoy describiendo aquí es totalmente inviable sin eso.
Robert Rossney

Lo que está describiendo es "Propiedades implementadas automáticamente". Desafortunadamente, con Visual Basic.NET, esto en realidad usa una variable de prefijo "oculto" detrás de escena, es decir, si tuviera una propiedad auto-implementada "Public Property Foo As Integer", NO podría tener la declaración de variable miembro "Private _foo as Entero "

No, no estoy describiendo propiedades implementadas automáticamente, al menos no en mi ejemplo. Estoy describiendo un nivel de alcance que no existe en C # o VB. Es realmente desafortunado que VB haya elegido una forma tan trivial de confundir los nombres de los campos de respaldo. C # es lo suficientemente feo como para que nunca cree una variable con el mismo nombre por accidente.
Robert Rossney

3

La notación _fieldName para campos privados es muy 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, violé tu convención de nomenclatura pero se 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 del tipo de un objeto delante del nombre de la variable, tiene su nivel de acceso.

Contraste esto con Ruby, donde el nombre de la variable @my_numbervincula el nombre al ámbito y es irrompible.

editar: esta respuesta se ha vuelto negativa. No me importa, se queda.


11
No es una crítica válida de una convención de nomenclatura decir que es posible que los desarrolladores no la sigan.
Robert Rossney el

8
Wow, tu definición de "fácil de romper" y la mía son, como, opuestos completos. El tuyo significa "fácil de romper intencionalmente", mientras que la mayoría de las otras personas probablemente significa "fácil de romper accidentalmente ". Lo dejaré como ejercicio para que el lector descubra cuál es más relevante al escribir código legible ...
Konrad Rudolph

66
@ Konrad: Suenas pretencioso cuando dices "como un ejercicio para el lector". Este no es un libro de texto de matemáticas.
jcollum

3
Ligeramente menos negativo ahora :) Si bien podemos estar remando contra la corriente, tampoco me gusta la convención de subrayado. En mi opinión, no es diferente de la notación húngara y, para ser honesto, hace que mis ojos sangren (duele la legibilidad). Lanzamos la notación húngara con C # y es hora de eliminar este último vestigio de no confiar en su IDE.
Tim Long

1
Escuché que MS en realidad dice que el guión bajo no debe usarse en su guía de estilo C #. blogs.msdn.microsoft.com/brada/2005/01/26/… - sección 2.6 - ¡parece que Brad Abrams está de acuerdo con nosotros al menos!
jcollum

1

Cuando desee que su ensamblado cumpla con CLS, puede usar el atributo CLSCompliant en su archivo de información de ensamblaje. El compilador se quejará cuando su código contenga cosas que no son compatibles con cls.

Luego, cuando tiene 2 propiedades que solo difieren en el caso, el compilador emitirá un error. Por otro lado, cuando tenga un campo privado y una propiedad pública en la misma clase, no habrá problemas.

(Pero, 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).


0

Me gusta usar guiones bajos delante de mis campos privados por dos razones. Ya se ha mencionado uno, los campos se destacan de sus propiedades asociadas en 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 #.


1
whoah, es eso sabio? ¿El subrayado no significa 'continúa en la línea siguiente' en VB?
JBRWilkinson

1
Solo si el guión bajo es seguido por un espacio.
Rob Windsor

La letra inicial en minúscula o mayúscula se destaca bien para mí :)
ManoDestra

0

No hay implicaciones de ningún tipo. Cuando se compila su código, todo lo que es importante para el compilador es el espacio de nombres y la visibilidad del campo / propiedad. Un guión bajo es tan significativo como cualquier otro carácter al nombrar un identificador. El verdadero truco es utilizar una convención que usted y las personas que lo rodean entenderán.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.