Diferencia en C # entre diferentes estilos getter

154

A veces veo abreviaturas en las propiedades del captador. Por ejemplo, esos dos tipos:

public int Number { get; } = 0

public int Number => 0;

¿Puede alguien decirme si hay alguna diferencia entre esos dos? ¿Cómo se comportan? ¿Ambos son de solo lectura?

WoIIe
fuente

Respuestas:

266

Sí, ambos son de solo lectura, pero hay una diferencia. En el primero, hay un campo de respaldo que se inicializa a 0 antes de que se ejecute el constructor. Puede cambiar el valor solo en el constructor , al igual que un campo de solo lectura normal. El captador en sí solo devuelve el valor del campo.

En el segundo, el getter solo devuelve 0 cada vez, sin ningún campo involucrado.

Entonces, para evitar el uso de propiedades implementadas automáticamente o miembros con cuerpo de expresión, tenemos:

Primera versión

private readonly int _number = 0;
public int Number { get { return _number; } }

Segunda versión

public int Number { get { return 0; } }

Un ejemplo más claro de la diferencia podría verse así:

public DateTime CreationTime { get; } = DateTime.UtcNow;
public DateTime CurrentTime => DateTime.UtcNow;

Si crea un solo objeto, su CreationTimepropiedad siempre dará el mismo resultado, ya que se almacena en un campo de solo lectura, inicializado en la construcción del objeto. Sin embargo, cada vez que acceda a la CurrentTimepropiedad, eso hará DateTime.UtcNowque se evalúe, por lo que obtendrá un resultado potencialmente diferente.

Jon Skeet
fuente
23
Tenga en cuenta que la segunda versión no siempre devuelve el mismo valor. Un buen ejemplo es si regresas random.NextInt(). La primera versión evaluará eso una vez y siempre tendrá el mismo valor. El segundo devolverá un nuevo valor cada vez.
248

Una diferencia es cuando eso 0se evalúa: en la creación del objeto o cuando se usa la propiedad.

Puede ver esto mejor con las propiedades de DateTime:

class SomeTestClass
{
    public DateTime Start { get; } = DateTime.Now;

    public DateTime Now => DateTime.Now;
}

La Startpropiedad sigue regresando la misma hora (de cuando se creó la instancia), mientras que Nowcambia para reflejar la hora actual.

Explicacion :

La primera versión ("Inicio") proporciona un valor inicial que incluso puede ser sobrescrito por el constructor. Entonces esto se evalúa solo una vez.
La segunda versión ("Ahora") proporciona la expresión que será el "captador" de esta propiedad. Entonces esto se evalúa cada vez que se lee la propiedad. Ni siquiera hay un campo de respaldo que el constructor pueda sobrescribir.

Hans Kein
fuente
26
Esta es la distinción más importante, creo.
Mateo
14
La respuesta aceptada define con mayor precisión la diferencia en el código de ejemplo, pero esto explica una diferencia más útil en las dos estructuras.
Kamil Drakari
3
Wow, obtuviste más votos positivos que el famoso Jon Skeet.
machine_1
21

Estas son las características del lenguaje C # 6.

Primer ejemplo

public int Number { get; } = 0

El primer ejemplo es una propiedad automática solo para captadores . El campo de respaldo de una propiedad automática solo getter se declara implícitamente como de solo lectura.

Segundo ejemplo

public int Number => 0;

Y el segundo ejemplo son los cuerpos de expresión en miembros de funciones similares a propiedades . Tenga en cuenta que no hay ninguna getpalabra clave: está implícito en el uso de la sintaxis del cuerpo de la expresión.

Ambos son de solo lectura.

Jehof
fuente
55
... pero como explica Jon Skeet, puede cambiar el valor que devuelve el primero.
Martin Bonner apoya a Monica el
2
@MartinBonner ... pero solo en el constructor.
Dennis Kuypers
55
o, como siempre, a través de la reflexión (nitpicking menor)
Marco Pf