Українська
Захист стану та поля readonly
Захист стану об’єкта
Приховати поле недостатньо, якщо клас видає назовні посилання на свій внутрішній змінний об’єкт. Типові прийоми захисту стану:
- властивості з обмеженим записом:
{ get; private set; }– змінюється лише всередині класу;{ get; init; }– задається лише під час створення;{ get; }– лише в конструкторі; - методи-команди замість сеттерів: замість
account.Balance = 500методDeposit(amount), що виражає дію предметної області й перевіряє її; - захисні копії (defensive copies): якщо клас зберігає масив, властивість не повинна повертати сам масив, бо тоді зовнішній код змінить його елементи в обхід перевірок. Метод повертає копію:
return operations[..count];
cs
var bad = new BadGroup();
bad.Grades[0] = -100; // стан змінено в обхід класу
Console.WriteLine(bad.Grades[0]); // -100
var good = new GoodGroup();
good.GetGrades()[0] = -100; // змінюється лише копія
Console.WriteLine(good.GetGrades()[0]); // 90
class BadGroup
{
public int[] Grades { get; } = [90, 75, 82];
}
class GoodGroup
{
private readonly int[] grades = [90, 75, 82];
public int[] GetGrades() => (int[])grades.Clone();
}Властивість { get; } у класі BadGroup забороняє присвоїти інший масив, але не забороняє змінювати елементи наявного: readonly захищає посилання, а не вміст об’єкта.
Поля const, readonly і static readonly
const– константа часу компіляції: значення відоме компілятору й підставляється в місце використання. Дозволено лише прості типи (int,double,decimal,bool,char,string). Константа неявно статична: звертаються через ім’я класуValidation.MaxAge;readonly– поле екземпляра, яке можна присвоїти лише під час оголошення або в конструкторі; значення може бути різним для різних об’єктів і обчислюватися під час виконання;static readonly– одне значення на клас, яке обчислюється під час виконання один раз (в оголошенні або статичному конструкторі): поточна дата запуску, об’єкт-зразок, ставка з налаштувань (https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/readonly).
Якщо значення справді незмінне за визначенням (кількість днів у тижні, π), використовують const. Якщо воно може змінитися в майбутніх версіях або має тип, недоступний для const (наприклад, об’єкт класу), використовують static readonly.