variable programming practices net microsoft guidelines convenciones coding codigo code classes best and c# coding-style this

programming - convenciones de codigo c#



¿Cuándo usas la palabra clave “this”? (30)

Tenía curiosidad acerca de cómo otras personas usan esta palabra clave. Tiendo a usarlo en constructores, pero también puedo usarlo en toda la clase en otros métodos. Algunos ejemplos:

En un constructor:

public Light(Vector v) { this.dir = new Vector(v); }

En otra parte

public void SomeMethod() { Vector vec = new Vector(); double d = (vec * vec) - (this.radius * this.radius); }


this en un compilador de C ++

El compilador de C ++ buscará silenciosamente un símbolo si no lo encuentra inmediatamente. A veces, la mayoría de las veces, es bueno:

  • utilizando el método de la clase madre si no lo ha sobrecargado en la clase secundaria.
  • Promover un valor de un tipo en otro tipo.

Pero a veces, simplemente no quieres que el compilador adivine. Quieres que el compilador recoja el símbolo correcto y no otro.

Para mí , esos momentos son cuando, dentro de un método, quiero acceder a un método miembro o variable miembro. Simplemente no quiero que se recoja un símbolo aleatorio solo porque escribí printf lugar de print . this->printf no se habría compilado.

El punto es que, con las bibliotecas heredadas de C (§), el código heredado escrito hace años (§§), o lo que pueda suceder en un lenguaje donde copiar / pegar es una característica obsoleta pero aún activa, a veces le dice al compilador que no juegue El ingenio es una gran idea.

Estas son las razones por las que uso this .

(§) para mí todavía es un misterio, pero ahora me pregunto si el hecho de que incluya el encabezado <windows.h> en su fuente, es la razón por la que todos los símbolos de las bibliotecas C heredadas contaminarán su espacio de nombres global

(§§) darse cuenta de que "debes incluir un encabezado, pero que incluir este encabezado romperá tu código porque usa una macro tonta con un nombre genérico" es uno de esos momentos de la ruleta rusa en la vida de un codificador


''esta.'' ayuda a encontrar miembros en la clase ''this'' con muchos miembros (generalmente debido a una cadena de herencia profunda).

Golpear CTRL + Space no ayuda con esto, porque también incluye tipos; donde-como ''esto''. Incluye miembros SOLAMENTE.

Por lo general, lo elimino una vez que tengo lo que buscaba, pero este es solo mi estilo.

En términos de estilo, si eres un guardabosques solitario, tú decides; Si trabaja para una empresa, apéguese a la política de la compañía (observe las cosas en el control de código fuente y vea lo que otras personas están haciendo). En términos de uso para calificar a los miembros, ninguno es correcto o incorrecto. Lo único incorrecto es la inconsistencia, esa es la regla de oro del estilo. Deja a los demás recogiendo liendres. Pase su tiempo reflexionando sobre problemas reales de codificación, y obviamente codificación.


1 - El lenguaje común de Java:

public void setFoo(int foo) { this.foo = foo; }

2 - Al llamar a una función con este objeto como parámetro

notifier.addListener(this);


Aquí es cuando lo uso:

  • Acceso a métodos privados desde dentro de la clase (para diferenciar)
  • Pasar el objeto actual a otro método (o como un objeto remitente, en caso de un evento)
  • Al crear métodos de extensión: D

No uso esto para los campos privados porque prefijo los nombres de las variables de los campos privados con un guión bajo (_).


Cada vez que necesite una referencia al objeto actual.

Un escenario particularmente útil es cuando su objeto está llamando a una función y quiere pasar a sí mismo a ella.

Ejemplo:

void onChange() { screen.draw(this); }


Cuando hay muchos desarrolladores trabajando en la misma base de código, necesita algunas pautas / reglas de código. Donde trabajo, decidimos usar ''esto'' en campos, propiedades y eventos.

Para mí tiene sentido hacerlo de esta manera, hace que el código sea más fácil de leer cuando se diferencian entre variables de clase y variables de método.


Depende de la norma de codificación bajo la que estoy trabajando. Si estamos usando _ para denotar una variable de instancia, entonces "esto" se vuelve redundante. Si no estamos usando _, tiendo a usar esto para denotar la variable de instancia.


En la respuesta de Jakub Šturc, su número 5 sobre el paso de datos entre constructores probablemente podría necesitar una pequeña explicación. Esto está en la sobrecarga de constructores y es el único caso donde el uso de this es obligatorio. En el siguiente ejemplo, podemos llamar al constructor parametrizado desde el constructor sin parámetros con un parámetro predeterminado.

class MyClass { private int _x public MyClass() : this(5) {} public MyClass(int v) { _x = v;} }

He encontrado que esta es una característica particularmente útil en ocasiones.


Hay un uso que aún no se ha mencionado en C ++, y que no es para referirse al propio objeto o desambiguar un miembro de una variable recibida.

Puede usar this para convertir un nombre no dependiente en un nombre dependiente de argumento dentro de las clases de plantilla que heredan de otras plantillas.

template <typename T> struct base { void f() {} }; template <typename T> struct derived : public base<T> { void test() { //f(); // [1] error base<T>::f(); // quite verbose if there is more than one argument, but valid this->f(); // f is now an argument dependent symbol } }

Las plantillas se compilan con un mecanismo de dos pases. Durante la primera pasada, solo se resuelven y verifican los nombres no dependientes de los argumentos, mientras que los nombres dependientes se verifican solo por coherencia, sin sustituir los argumentos de la plantilla.

En ese paso, sin realmente sustituir el tipo, el compilador casi no tiene información de lo que podría ser la base<T> (tenga en cuenta que la especialización de la plantilla base puede convertirla en tipos completamente diferentes, incluso tipos indefinidos), por lo que simplemente asume que es un tipo En esta etapa, la llamada no dependiente f que parece simplemente natural para el programador es un símbolo que el compilador debe encontrar como miembro de espacios de nombres derived o adjuntos, lo que no ocurre en el ejemplo, y se quejará.

La solución está convirtiendo el nombre no dependiente f en un nombre dependiente. Esto se puede hacer de varias maneras, indicando explícitamente el tipo de implementación ( base<T>::f - al agregar la base<T> el símbolo depende de T y el compilador simplemente asumirá que existe y pospone la verificación real para el segundo paso, después de la sustitución del argumento.

La segunda forma, mucho más ordenada si hereda de plantillas que tienen más de un argumento, o nombres largos, es simplemente agregar this-> antes del símbolo. Como la clase de plantilla que está implementando depende de un argumento (hereda de la base<T> ), this-> depende del argumento, y obtenemos el mismo resultado: this->f se verifica en la segunda ronda, después de la sustitución del parámetro de la plantilla .


Hay varios usos de this palabra clave en C #.

  1. Para calificar miembros ocultos por nombre similar
  2. Para tener un objeto pasar a sí mismo como un parámetro a otros métodos
  3. Para que un objeto se devuelva desde un método.
  4. Declarar indexadores
  5. Declarar métodos de extensión.
  6. Pasar parámetros entre constructores.
  7. Para reasignar internamente valor de tipo de valor (estructura) .
  8. Para invocar un método de extensión en la instancia actual
  9. Castearse a otro tipo.
  10. Para encadenar constructores definidos en la misma clase.

Puede evitar el primer uso al no tener variables miembro y locales con el mismo nombre en el alcance, por ejemplo, siguiendo las convenciones comunes de nomenclatura y utilizando propiedades (caso Pascal) en lugar de campos (caso de camello) para evitar chocar con variables locales (también camello caso). En C # 3.0, los campos se pueden convertir en propiedades fácilmente mediante el uso de propiedades implementadas automáticamente .


Lo uso cada vez que me refiero a una variable de instancia, incluso si no lo necesito. Creo que hace que el código sea más claro.


Lo uso cada vez que puedo. Creo que hace que el código sea más legible, y un código más legible equivale a menos errores y más mantenimiento.



Lo uso cuando, en una función que acepta una referencia a un objeto del mismo tipo, quiero dejar perfectamente claro a qué objeto me refiero, a dónde.

Por ejemplo

class AABB { // ... members bool intersects( AABB other ) { return other.left() < this->right() && this->left() < other.right() && // +y increases going down other.top() < this->bottom() && this->top() < other.bottom() ; } } ;

(vs)

class AABB { bool intersects( AABB other ) { return other.left() < right() && left() < other.right() && // +y increases going down other.top() < bottom() && top() < other.bottom() ; } } ;

De un vistazo, ¿a qué se refiere AABB right() ? this añade un poco de clarificador.


Lo uso en cualquier lugar donde pueda haber ambigüedad (obviamente). No solo la ambigüedad del compilador (que se requeriría en ese caso), sino también la ambigüedad para alguien que mira el código.


Lo uso para invocar a Intellisense como JohnMcG , pero volveré y borrare "this->" cuando termine. Sigo la convención de Microsoft de prefijar las variables miembro con "m_", por lo que dejarlo como documentación sería redundante.


Lo uso solo cuando es necesario, a excepción de las operaciones simétricas que, debido al argumento único, el polimorfismo se deben poner en los métodos de un lado:

boolean sameValue (SomeNum other) { return this.importantValue == other.importantValue; }


Me acostumbré a usarlo generosamente en Visual C ++, ya que hacerlo activaría IntelliSense. Presioné la tecla ''>'' y soy perezoso. (y propenso a errores tipográficos)

Pero continué usándolo, ya que me parece útil ver que estoy llamando a una función miembro en lugar de una función global.


No debes usar "esto" a menos que sea absolutamente necesario.

Hay una penalización asociada con verbosidad innecesaria. Debe esforzarse por obtener un código que sea exactamente el tiempo que debe ser, y ya no.


No puedo creer que todas las personas que dicen que usarlo siempre son "mejores prácticas" y demás.

Use "esto" cuando haya ambigüedad, como en el ejemplo de Corey o cuando necesite pasar el objeto como parámetro, como en el ejemplo de Ryan . No hay razón para usarlo de otra manera porque ser capaz de resolver una variable basada en la cadena de alcance debe ser lo suficientemente claro como para que las variables calificadas con él no sean necesarias.

EDITAR: La documentación de C # sobre "esto" indica un uso más, además de los dos que mencioné, para la palabra clave "this": para declarar los indexadores

EDITAR: @Juan: Huh, no veo ninguna inconsistencia en mis afirmaciones: hay 3 instancias en las que usaría la palabra clave "this" (como se documenta en la documentación de C #), y esas son ocasiones en las que realmente lo necesita . Poner "esto" frente a las variables en un constructor cuando no hay sombras en curso es simplemente una pérdida de pulsaciones de teclas y una pérdida de mi tiempo al leerlo, no proporciona ningún beneficio.


No quiero decir que esto suene snarky, pero no importa.

Seriamente.

Mire las cosas que son importantes: su proyecto, su código, su trabajo, su vida personal. Ninguno de ellos tendrá su éxito basado en si utiliza o no la palabra clave "this" para calificar el acceso a los campos. Esta palabra clave no le ayudará a enviar a tiempo. No reducirá los errores, no tendrá ningún efecto apreciable en la calidad del código o la capacidad de mantenimiento. No le conseguirá un aumento de sueldo ni le permitirá pasar menos tiempo en la oficina.

Es realmente solo un problema de estilo. Si te gusta "esto", entonces úsalo. Si no lo haces, entonces no lo hagas. Si lo necesitas para obtener la semántica correcta, entonces úsalo. La verdad es que cada programador tiene su propio estilo de programación único. Ese estilo refleja las nociones de ese programador en particular de cómo debería ser el "código más estéticamente agradable". Por definición, cualquier otro programador que lea su código tendrá un estilo de programación diferente. Eso significa que siempre va a haber algo que hiciste que el otro chico no le gusta, o habría hecho diferente. En algún momento, un tipo leerá tu código y se quejará de algo.

No me preocuparía por eso. Solo me aseguraría de que el código sea lo más estéticamente agradable posible de acuerdo con sus propios gustos. Si le pregunta a 10 programadores cómo formatear el código, obtendrá unas 15 opiniones diferentes. Una cosa mejor para centrarse es cómo se factoriza el código. ¿Son las cosas abstractas correctas? ¿Elegí nombres significativos para las cosas? ¿Hay mucha duplicación de código? ¿Hay formas de simplificar las cosas? Creo que lograr que esas cosas salgan bien tendrá el mayor impacto positivo en su proyecto, su código, su trabajo y su vida. Casualmente, probablemente también hará que el otro se queje menos. Si su código funciona, es fácil de leer y está bien factorizado, el otro individuo no va a examinar cómo inicializar los campos. Solo va a usar su código, se maravilla de su grandeza y luego pasa a otra cosa.


Otro uso un tanto raro de esta palabra clave es cuando necesita invocar una implementación de interfaz explícita desde la clase de implementación. Aquí hay un ejemplo artificial:

class Example : ICloneable { private void CallClone() { object clone = ((ICloneable)this).Clone(); } object ICloneable.Clone() { throw new NotImplementedException(); } }


Personalmente, trato de usar esto siempre cuando me refiero a las variables miembro. Ayuda a aclarar el código y hacerlo más legible. Incluso si no hay ambigüedad, alguien que lea mi código por primera vez no lo sabe, pero si ve que se usa constantemente, sabrá si está viendo una variable miembro o no.


Prácticamente solo uso esto cuando se hace referencia a una propiedad de tipo desde dentro del mismo tipo. Como mencionó otro usuario, también subrayo los campos locales para que sean evidentes sin necesidad de esto .


Siempre debe usarlo, lo uso para diferenciar campos y parámetros privados (debido a que nuestras convenciones de nomenclatura establecen que no usamos prefijos para nombres de miembros y parámetros (y se basan en la información que se encuentra en Internet), por lo que considero que mejores prácticas))


Solo lo uso cuando es absolutamente necesario, es decir, cuando otra variable está siguiendo a otra. Tales como aquí:

class Vector3 { float x; float y; float z; public Vector3(float x, float y, float z) { this.x = x; this.y = y; this.z = z; } }

O como Ryan Fox señala, cuando necesitas pasar esto como un parámetro. (Las variables locales tienen prioridad sobre las variables miembro)


También tiendo a usarlo en todas partes, solo para asegurarme de que está claro que son los miembros de la instancia con los que estamos tratando.


Tiendo a subrayar los campos con _ así que nunca necesito usar esto. También R # tiende a refactorizarlos de todos modos ...


[C ++]

Estoy de acuerdo con el "uso cuando tienes que" brigada. Decorar el código innecesariamente con esto no es una gran idea porque el compilador no te advertirá cuando te olvides de hacerlo. Esto introduce una posible confusión para las personas que esperan que esto siempre esté allí, es decir, tendrán que pensar en ello.

Entonces, ¿cuándo lo usarías? Acabo de echar un vistazo a un código aleatorio y he encontrado estos ejemplos (no estoy juzgando si son buenas cosas para hacer o no):

  • Pasar "a ti mismo" a una función.
  • Asignar "a ti mismo" a un puntero o algo así.
  • Fundición, es decir, fundición arriba / abajo (segura o no), constancia de expulsión, etc.
  • Compilación forzada desambiguación.

[C ++]

esto se usa en el operador de asignación donde la mayoría de las veces tiene que verificar y prevenir cosas extrañas (no intencionales, peligrosas o simplemente una pérdida de tiempo para el programa) como:

A a; a = a;

Su operador de asignación será escrito:

A& A::operator=(const A& a) { if (this == &a) return *this; // we know both sides of the = operator are different, do something... return *this; }