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


100

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

private readonly double Fuel= 0;

public double FuelConsumption
{
    get
    {
        return Fuel;
    }
}        

или

private double Fuel= 0;

public double FuelConsumption
{
     get
     {
          return Fuel;
     }
}

12
для C #> 5 свойство get может быть уменьшено доpublic double FuelConsumption => Fuel;
— meJustAndrew 03

Ответы:


122

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

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

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
}

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

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

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

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

Короче говоря, если вам нужно убедиться, что значение вашего свойства никогда не будет изменено извне, но вам нужно иметь возможность изменять его изнутри кода класса, используйте свойство «только для получения».

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


14
+1 для примера кода. Но необходимо прояснить, что свойства "только для получения" могут быть изменены методами класса только тогда, когда они заключены в поля класса. Они не могут быть изменены напрямую даже методами класса, если установщика нет. И попытка сделать это приведет к ошибке компилятора.
— Деврадж Гадхави

13

Начиная с C # 6, вы можете объявить и инициализировать «автоматическое свойство только для чтения» в одной строке:

double FuelConsumption { get; } = 2;

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


7

Говорят, что свойство, имеющее только геттер, доступно только для чтения. Причина, по которой не предоставляется сеттер для изменения значения свойства (извне).

В C # есть ключевое слово только для чтения , которое можно использовать в полях (не в свойствах). Поле, помеченное как «только для чтения», может быть установлено только один раз во время построения объекта (в конструкторе).

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

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

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

взято из примера Марка:

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

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


0

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.