Quand utiliser les propriétés Readonly et Get only

100

Dans une application .NET, quand dois-je utiliser les propriétés "ReadOnly" et quand dois-je utiliser simplement "Get". Quelle est la différence entre ces deux.

private readonly double Fuel= 0;

public double FuelConsumption
{
    get
    {
        return Fuel;
    }
}        

ou

private double Fuel= 0;

public double FuelConsumption
{
     get
     {
          return Fuel;
     }
}
RAM
la source
12
pour C #> 5, la propriété get peut être réduite àpublic double FuelConsumption => Fuel;
meJustAndrew

Réponses:

121

La création d'une propriété avec uniquement un getter rend votre propriété en lecture seule pour tout code en dehors de la classe.

Vous pouvez cependant modifier la valeur à l'aide des méthodes fournies par votre 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
}

Définir le champ privé de votre classe comme readonlyvous permet de définir la valeur du champ une seule fois (à l'aide d'une affectation en ligne ou dans le constructeur de classe). Vous ne pourrez pas le modifier plus tard.

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

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

readonly Les champs de classe sont souvent utilisés pour les variables qui sont initialisées lors de la construction de la classe et ne seront jamais modifiés par la suite.

En bref, si vous devez vous assurer que la valeur de votre propriété ne sera jamais modifiée de l'extérieur, mais que vous devez être en mesure de la modifier à partir de votre code de classe, utilisez une propriété "Get-only".

Si vous avez besoin de stocker une valeur qui ne changera jamais une fois sa valeur initiale définie, utilisez un readonlychamp.

Thibault Falise
la source
14
+ 1 pour exemple de code. Mais il faut préciser que les propriétés "Get-Only" ne peuvent être modifiées par les méthodes de classe que lorsqu'elles sont encapsulées sur des champs de classe. Ils ne peuvent pas être modifiés directement même par les méthodes de classe, si le setter n'est pas là. Et essayer de le faire entraînerait une erreur du compilateur.
Devraj Gadhavi
13

À partir de C # 6, vous pouvez déclarer et initialiser une `` propriété automatique en lecture seule '' sur une seule ligne:

double FuelConsumption { get; } = 2;

Vous pouvez définir la valeur à partir du constructeur mais pas d'autres méthodes.

Colonel Panic
la source
7

Une propriété qui n'a qu'un getter est dite en lecture seule. Car aucun setter n'est fourni, pour changer la valeur de la propriété (de l'extérieur).

C # a un mot-clé en lecture seule , qui peut être utilisé sur les champs (pas les propriétés). Un champ marqué comme "lecture seule" ne peut être défini qu'une seule fois lors de la construction d'un objet (dans le constructeur).

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
la source
2

Les propriétés readonly sont utilisées pour créer un code de sécurité. j'aime beaucoup la série de publications d'encapsulation de Mark Seemann sur les propriétés et les champs de sauvegarde:

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

tiré de l'exemple 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;
    }
}

dans cet exemple, vous utilisez le champ de nom en lecture seule pour vous assurer que l'invariant de classe est toujours valide. dans ce cas, le compositeur de classe voulait s'assurer que le champ de nom est défini une seule fois (immuable) et est toujours présent.

danfromisrael
la source
0

Les méthodes suggèrent que quelque chose doit se produire pour renvoyer la valeur, les propriétés suggèrent que la valeur est déjà là. C'est une règle de base, parfois vous voudrez peut-être une propriété qui fait un peu de travail (c'est-à-dire Count), mais en général, c'est un moyen utile de décider.

Neil Barnwell
la source