Cuándo se deben usar las propiedades Readonly y Get only

100

En una aplicación .NET, ¿cuándo debo usar las propiedades "ReadOnly" y cuándo debo usar solo "Get"? Cuál es la diferencia entre estos dos.

private readonly double Fuel= 0;

public double FuelConsumption
{
    get
    {
        return Fuel;
    }
}        

o

private double Fuel= 0;

public double FuelConsumption
{
     get
     {
          return Fuel;
     }
}
RAM
fuente
12
para C #> 5, la propiedad get se puede reducir apublic double FuelConsumption => Fuel;
meJustAndrew

Respuestas:

121

Crear una propiedad con solo un captador hace que su propiedad sea de solo lectura para cualquier código que esté fuera de la clase.

Sin embargo, puede cambiar el valor utilizando los métodos proporcionados por su clase:

public class FuelConsumption {
    private double fuel;
    public double Fuel
    {
        get { return this.fuel; }
    }
    public void FillFuelTank(double amount)
    {
        this.fuel += amount;
    }
}

public static void Main()
{
    FuelConsumption f = new FuelConsumption();

    double a;
    a = f.Fuel; // Will work
    f.Fuel = a; // Does not compile

    f.FillFuelTank(10); // Value is changed from the method's code
}

Establecer el campo privado de su clase como le readonlypermite establecer el valor del campo solo una vez (usando una asignación en línea o en el constructor de la clase). No podrá cambiarlo más tarde.

public class ReadOnlyFields {
    private readonly double a = 2.0;
    private readonly double b;

    public ReadOnlyFields()
    {
        this.b = 4.0;
    }
}

readonly Los campos de clase se utilizan a menudo para las variables que se inicializan durante la construcción de la clase y nunca se cambiarán más adelante.

En resumen, si necesita asegurarse de que el valor de su propiedad nunca se cambiará desde el exterior, pero necesita poder cambiarlo desde el código de su clase, use una propiedad "Get-only".

Si necesita almacenar un valor que nunca cambiará una vez que se haya establecido su valor inicial, use un readonlycampo.

Thibault Falise
fuente
14
+ 1 para ejemplo de código. Pero es necesario aclarar que las propiedades "Get-Only" solo pueden ser modificadas por los métodos de la clase cuando están incluidas en los campos de la clase. No se pueden modificar directamente ni siquiera mediante los métodos de clase, si el establecedor no está allí. E intentarlo resultaría en un error del compilador.
Devraj Gadhavi
13

A partir de C # 6 , puede declarar e inicializar una 'propiedad automática de solo lectura' en una línea:

double FuelConsumption { get; } = 2;

Puede establecer el valor del constructor pero no de otros métodos.

Coronel Panic
fuente
7

Se dice que una propiedad que solo tiene un getter es de solo lectura. Porque no se proporciona ningún setter, para cambiar el valor de la propiedad (desde fuera).

C # tiene una palabra clave de solo lectura , que se puede usar en campos (no propiedades). Un campo que está marcado como "solo lectura", solo se puede establecer una vez durante la construcción de un objeto (en el constructor).

private string _name = "Foo"; // field for property Name;
private bool _enabled = false; // field for property Enabled;

public string Name{ // This is a readonly property.
  get {
    return _name;  
  }
}

public bool Enabled{ // This is a read- and writeable property.
  get{
    return _enabled;
  }
  set{
    _enabled = value;
  }
} 
Jehof
fuente
2

Las propiedades de solo lectura se utilizan para crear un código a prueba de fallos. Me gusta mucho la serie de publicaciones de Encapsulación de Mark Seemann sobre propiedades y campos de respaldo:

http://blog.ploeh.dk/2011/05/24/PokayokeDesignFromSmellToFragrance.aspx

tomado del ejemplo de Mark:

public class Fragrance : IFragrance
{
    private readonly string name;

    public Fragrance(string name)
    {
        if (name == null)
        {
            throw new ArgumentNullException("name");
        }

        this.name = name;
    }

    public string Spread()
    {
        return this.name;
    }
}

en este ejemplo, usa el campo de nombre de solo lectura para asegurarse de que la clase invariante sea siempre válida. en este caso, el compositor de la clase quería asegurarse de que el campo de nombre se establezca solo una vez (inmutable) y esté siempre presente.

danfromisrael
fuente
0

Los métodos sugieren que algo tiene que suceder para devolver el valor, las propiedades sugieren que el valor ya está allí. Esta es una regla general, a veces es posible que desee una propiedad que haga un poco de trabajo (es decir Count), pero generalmente es una forma útil de decidir.

Neil Barnwell
fuente