¿Cómo puedo acceder a la variable de respaldo de una propiedad implementada automáticamente?

79

En el pasado, declaramos propiedades como esta:

public class MyClass
{
    private int _age;

    public int Age
    {
          get{ return _age;  }
          set{ _age = value; }
    }
}

Ahora podemos hacer:

public class MyClass
{
    public int Age {get; set;} 
}

Mi pregunta es, ¿cómo puedo acceder a la variable privada que se crea automáticamente usando esta notación?

Prefiero acceder a la variable privada y no al acceso público 'Edad'. ¿Existe una notación predeterminada para acceder a la variable privada o simplemente no es posible?

público estático
fuente
10
¿Cuál es la diferencia en este caso de acceder al accesor privado frente al público? Creo que es una buena práctica acceder al descriptor de acceso público incluso desde la lógica en la clase de declaración. Si alguna vez agrega algo de lógica al descriptor de acceso, no querrá tener que cambiar todo su código.
Eric Schoonover
@ cuchara16 ¿Puedes darme un ejemplo de cómo agregar lógica al descriptor de acceso y tener que cambiar todo tu código como resultado? Realmente no entendí esta parte.
Ogen

Respuestas:

92

El objetivo de las nuevas propiedades automáticas es reducir la cantidad de código repetitivo que necesita escribir cuando solo tiene una propiedad simple que no necesita ninguna lógica especial en get o set.

Si desea acceder al miembro privado que utilizan estas propiedades, suele ser por algunas razones:

  • Necesita algo más que un simple get / set; en este caso, debe evitar el uso de propiedades automáticas para este miembro.
  • Desea evitar el impacto de rendimiento de pasar por el get o set y simplemente usar el miembro directamente; en este caso, me sorprendería si realmente hubiera un éxito de rendimiento. Los miembros simples get / set son muy fáciles de integrar, y en mis pruebas (ciertamente limitadas) no he encontrado una diferencia entre usar las propiedades automáticas y acceder al miembro directamente.
  • Solo desea tener acceso de lectura público (es decir, solo un 'get') y la clase escriba directamente al miembro; en este caso, puede usar un conjunto privado en su propiedad automática. es decir

    public class MyClass
    {
        public int Age {get; private set;} 
    }

Esto generalmente cubre la mayoría de las razones para querer llegar directamente al campo de respaldo utilizado por las propiedades automáticas.

Wilka
fuente
Es cierto: reducen el código de la placa de bolos y también anunciaré que reducen lo que necesita probar. Algunos podrían argumentar que necesita probar la obtención / configuración manual pero no con propiedades automáticas, ya que puede confiar en el marco.
Daniel Auger
3
El ejemplo de código es incorrecto aquí. Debe ser public class MyClass {public int Age {get; conjunto privado;}} Estoy de acuerdo con esta respuesta. No puede acceder al campo privado y, si es necesario, no debería utilizar Propiedades automáticas en primer lugar.
hwiechers
hwiechers, gracias por eso. Tuve esa edición, pero cuando intenté arreglar el formateo, debí presionar pegar nuevamente y eliminar el bloque de código incorrecto. Doh!
Wilka
De uso común en objetos POCO
RobS
23

Su uso de propiedades automáticas implica que no necesita ninguna lógica de obtención / configuración para la propiedad, por lo que una variable de respaldo privada no es necesaria.

No use propiedades automáticas si tiene alguna lógica compleja en su clase. Simplemente vaya a private int _agegetters / setters normales como lo haría normalmente.

En mi opinión, las propiedades automáticas son más adecuadas para implementar rápidamente objetos desechables o cápsulas de datos temporales como:

public class TempMessage {
    public int FromID { get; set; }
    public int ToID { get; set; }
    public string Message { get; set; }
}

Donde no necesitas mucha lógica.

chakrit
fuente
¿Por qué agregar lógica compleja a su clase afectaría si usó o no propiedades automáticas dentro de esa clase?
Eric Schoonover
Es más una cuestión de coherencia ... si tiene una lógica compleja, querrá acceder a ella desde la variable de respaldo privada según las prácticas de OO ... y si usa propiedades automáticas, entonces ... habrá inconsistencias al acceder a esas propiedades . ya que algunos tendrán el prefijo de subrayado y otros no.
chakrit
12

Esta sintaxis se denomina comúnmente "azúcar sintáctica", lo que significa que el compilador toma esa sintaxis y la traduce a otra cosa. En su ejemplo, el compilador generaría un código que se parece a esto:

[CompilerGenerated]
private int <Age>k_BackingField;

public int Age
{
   [CompilerGenerated]
   get
   {
      return this.<Age>k_BackingField;
   }
   [CompilerGenerated]
   set
   {
      this.<Age>k_BackingField = value;
   }

Incluso sabiendo todo eso, probablemente podría acceder al campo de respaldo directamente, pero eso frustra el propósito de usar propiedades automáticas. Digo probablemente aquí porque depende de un detalle de implementación que podría cambiar en cualquier momento en una versión futura del compilador de C #.

Scott Dorman
fuente
10

Detrás de escena, lo que sucede es la inyección de una variable miembro privada, con el prefijo <> k__AutomaticallyGeneratedPropertyField #

De C # 3.0 Explicación de las propiedades automáticas

Aunque puede ser posible usar ese miembro privado directamente, es muy peligroso e innecesario.

macbirdie
fuente
7

No debería, y es muy poco probable que lo necesite. Si necesita acceder a la propiedad, use la propiedad pública (por ejemplo, this.Age). No hay nada especial en el campo privado que respalda la propiedad pública, usarlo con preferencia a la propiedad es solo una superstición.

Cuña
fuente
1
Siempre me pregunté cuál era el objetivo de las propiedades automáticas. Si no tienes una lógica especial en tus getters y setters, ¿por qué tenerlos?
Matthew Lock
4
Flexibilidad de @MatthewLock. Con el acceso directo al campo, está bloqueado en ese diseño a menos que cambie todo el código del cliente al mismo tiempo. Pero con una propiedad, si decide cambiarla de un "pseudocampo" a una propiedad calculada, o si decide agregar aserciones y verificaciones sobre el establecedor, o lo que sea, puede hacerlo de forma transparente. Esto es aún más útil si está escribiendo código de biblioteca, donde no puede controlar todo el código del cliente.
Miércoles
2

No se puede, es una función de idioma a diferencia de una función IDE. Para ser honesto, preferiría que IDE agregue la variable privada por usted. Estoy de acuerdo en que es un poco extraño que la clase tenga que usar internamente el punto de entrada público para acceder a sus propias variables. Por lo tanto, yo mismo no uso mucho esta nueva función.

Quisquilloso
fuente