Quando utilizzare Readonly e Get only properties


100

In un'applicazione .NET quando dovrei usare le proprietà "ReadOnly" e quando dovrei usare solo "Get". Qual è la differenza tra questi due.

private readonly double Fuel= 0;

public double FuelConsumption
{
    get
    {
        return Fuel;
    }
}        

o

private double Fuel= 0;

public double FuelConsumption
{
     get
     {
          return Fuel;
     }
}

12
per C #> 5 la proprietà get può essere ridotta apublic double FuelConsumption => Fuel;
meJustAndrew

Risposte:


121

La creazione di una proprietà con solo un getter rende la proprietà di sola lettura per qualsiasi codice che si trova al di fuori della classe.

Puoi comunque modificare il valore utilizzando i metodi forniti dalla tua classe:

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
}

L'impostazione del campo privato della classe come readonlyconsente di impostare il valore del campo solo una volta (utilizzando un'assegnazione in linea o nel costruttore della classe). Non potrai modificarlo in seguito.

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

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

readonly i campi di classe vengono spesso utilizzati per le variabili che vengono inizializzate durante la costruzione della classe e non verranno mai modificate in seguito.

In breve, se hai bisogno di assicurarti che il valore della tua proprietà non venga mai cambiato dall'esterno, ma devi essere in grado di cambiarlo dall'interno del codice della tua classe, usa una proprietà "Get-only".

Se è necessario memorizzare un valore che non cambierà mai una volta impostato il valore iniziale, utilizzare un readonlycampo.


14
+1 per esempio di codice. Ma è necessario chiarire che le proprietà "Get-Only" possono essere modificate solo dai metodi della classe quando sono racchiuse nei campi della classe. Non possono essere modificati direttamente anche dai metodi di classe, se il setter non è presente. E provare a farlo risulterebbe in un errore del compilatore.
Devraj Gadhavi

13

A partire da C # 6 è possibile dichiarare e inizializzare una 'proprietà automatica di sola lettura' in una riga:

double FuelConsumption { get; } = 2;

È possibile impostare il valore dal costruttore ma non da altri metodi.


7

Si dice che una proprietà che ha solo un getter sia di sola lettura. Perché non viene fornito alcun setter, per modificare il valore della proprietà (dall'esterno).

C # ha una parola chiave readonly , che può essere utilizzata nei campi (non nelle proprietà). Un campo contrassegnato come "readonly" può essere impostato solo una volta durante la costruzione di un oggetto (nel costruttore).

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

2

le proprietà di sola lettura vengono utilizzate per creare un codice a prova di errore. mi piace molto la serie di post sull'incapsulamento di Mark Seemann sulle proprietà e sui campi di supporto:

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

tratto dall'esempio di Marco:

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

in questo esempio si utilizza il campo del nome di sola lettura per assicurarsi che l'invariante della classe sia sempre valida. in questo caso il compositore della classe voleva assicurarsi che il campo nome fosse impostato una sola volta (immutabile) e fosse sempre presente.


0

I metodi suggeriscono che deve accadere qualcosa per restituire il valore, le proprietà suggeriscono che il valore è già presente. Questa è una regola pratica, a volte potresti volere una proprietà che funzioni un po '(cioè Count), ma generalmente è un modo utile per decidere.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.