Когда следует использовать свойства Readonly и Get only

В .NET-приложении, когда следует использовать свойства "ReadOnly" и когда следует использовать только "Get". В чем разница между этими двумя.

private readonly double Fuel= 0;

public double FuelConsumption
{
    get
    {
        return Fuel;
    }
}        

или

private double Fuel= 0;

public double FuelConsumption
{
     get
     {
          return Fuel;
     }
}

Ответ 1

Создание свойства только с помощью геттера делает ваше свойство доступным только для чтения для любого кода, который находится вне класса.

Однако вы можете изменить значение с помощью методов, предоставляемых вашим классом:

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

Настройка частного поля вашего класса как readonly позволяет установить значение поля только один раз (используя встроенное назначение или в конструкторе класса). Вы не сможете изменить его позже.

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

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

readonly поля классов часто используются для переменных, которые инициализируются во время построения класса и никогда не будут изменены позже.

Короче говоря, если вам необходимо убедиться, что значение свойства никогда не будет изменено извне, , но, вам нужно будет изменить его изнутри вашего кода класса, используйте "Get-only".

Если вам нужно сохранить значение, которое никогда не изменится после его первоначального значения, используйте поле readonly.

Ответ 2

Свойство, которое имеет только геттер, называется readonly. Причина, по которой не установлен сеттер, изменить значение свойства (извне).

У С# есть ключевое слово readonly, которое может использоваться для полей (а не свойств). Поле, помеченное как "readonly", может быть установлено только один раз при построении объекта (в конструкторе).

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

Ответ 3

свойства readonly используются для создания отказобезопасного кода. Мне очень нравится серия сообщений Encapsulation Mark Seemann о свойствах и областях поддержки:

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

взятый из примера 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;
    }
}

в этом примере вы используете поле имени для чтения, чтобы убедиться, что инвариант класса всегда действителен. в этом случае композитор класса хотел удостовериться, что поле имени установлено только один раз (неизменный) и всегда присутствует.

Ответ 4

Начиная с С# 6 вы можете объявить и инициализировать "авто-свойство только для чтения" в одной строке:

double FuelConsumption { get; } = 2;

Вы можете установить значение из конструктора, но не другие методы.

Ответ 5

Методы предполагают, что должно произойти, чтобы вернуть значение, свойства показывают, что значение уже существует. Это эмпирическое правило, иногда вам может понадобиться свойство, которое выполняет небольшую работу (т.е. Count), но обычно это полезный способ решить.