Quando deve usar as propriedades Readonly e Get only


100

Em um aplicativo .NET, quando devo usar as propriedades "ReadOnly" e quando devo usar apenas "Get". Qual é a diferença entre esses dois.

private readonly double Fuel= 0;

public double FuelConsumption
{
    get
    {
        return Fuel;
    }
}        

ou

private double Fuel= 0;

public double FuelConsumption
{
     get
     {
          return Fuel;
     }
}

12
para C #> 5, a propriedade get pode ser reduzida apublic double FuelConsumption => Fuel;
meJustAndrew

Respostas:


121

Criar uma propriedade com apenas um getter torna sua propriedade somente leitura para qualquer código que esteja fora da classe.

No entanto, você pode alterar o valor usando métodos fornecidos por sua 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
}

Definir o campo privado de sua classe como readonlypermite que você defina o valor do campo apenas uma vez (usando uma atribuição embutida ou no construtor de classe). Você não poderá alterá-lo mais tarde.

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

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

readonly Os campos de classe são freqüentemente usados ​​para variáveis ​​que são inicializadas durante a construção da classe e nunca serão alteradas posteriormente.

Resumindo, se você precisa garantir que o valor de sua propriedade nunca seja alterado externamente, mas precisa ser capaz de alterá-lo de dentro do código da classe, use uma propriedade "Get-only".

Se você precisar armazenar um valor que nunca mudará depois que seu valor inicial for definido, use um readonlycampo.


14
+ 1 para exemplo de código. Mas é preciso deixar claro que as propriedades "Get-Only" só podem ser modificadas pelos métodos de classe quando são agrupadas nos campos de classe. Eles não podem ser modificados diretamente, mesmo pelos métodos da classe, se o configurador não estiver lá. E tentar fazer isso resultaria em um erro do compilador.
Devraj Gadhavi

13

A partir do C # 6, você pode declarar e inicializar uma 'propriedade automática somente leitura' em uma linha:

double FuelConsumption { get; } = 2;

Você pode definir o valor do construtor, mas não outros métodos.


7

Uma propriedade que tem apenas um getter é considerada somente leitura. Porque nenhum setter é fornecido, para alterar o valor da propriedade (de fora).

C # tem uma palavra-chave somente leitura , que pode ser usada em campos (não em propriedades). Um campo marcado como "somente leitura" só pode ser definido uma vez durante a construção de um objeto (no construtor).

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

propriedades somente leitura são usadas para criar um código à prova de falhas. Eu realmente gosto da série de posts Encapsulation de Mark Seemann sobre propriedades e campos de apoio:

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

tirado do exemplo 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;
    }
}

neste exemplo, você usa o campo de nome somente leitura para garantir que a invariante de classe seja sempre válida. neste caso, o compositor da classe queria ter certeza de que o campo de nome é definido apenas uma vez (imutável) e está sempre presente.


0

Os métodos sugerem que algo deve acontecer para retornar o valor, as propriedades sugerem que o valor já está lá. Esta é uma regra prática, às vezes você pode querer uma propriedade que funcione um pouco (ou seja Count), mas geralmente é uma maneira útil de decidir.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.