Ответ
Прямое обращение к публичным полям (public fields) или свойствам объекта без предварительной валидации его состояния — частая причина ошибок времени выполнения, главным образом NullReferenceException.
Пример проблемы:
public class UserProfile
{
// Публичное поле — плохая практика.
public Address HomeAddress;
}
public class Address
{
public string City { get; set; }
}
// Клиентский код
var user = new UserProfile();
// Поле HomeAddress не инициализировано, по умолчанию null.
Console.WriteLine(user.HomeAddress.City); // NullReferenceException!
Решения и best practices:
-
Инкапсуляция и использование свойств: Замена публичных полей на свойства с контролем доступа.
public class UserProfile { private Address _homeAddress; public Address HomeAddress { get => _homeAddress; set => _homeAddress = value ?? throw new ArgumentNullException(nameof(value)); } } -
Ленивая инициализация: Инициализация поля при первом обращении.
public class UserProfile { private Address _homeAddress; public Address HomeAddress { get { if (_homeAddress == null) _homeAddress = new Address(); // Или загрузить из БД return _homeAddress; } } } -
Проверка в клиентском коде (защитное программирование):
// Явная проверка if (user?.HomeAddress != null) { Console.WriteLine(user.HomeAddress.City); } // Использование null-условных операторов (C# 6+) Console.WriteLine(user?.HomeAddress?.City ?? "Address not set"); -
Использование паттерна Null Object: Возвращать специальный, «пустой» объект вместо null.
public class NullAddress : Address { public override string City => "[No City Specified]"; } // В свойстве getter: get => _homeAddress ?? new NullAddress(); -
Инициализация в конструкторе (наиболее предпочтительно): Гарантирует, что объект создается в валидном состоянии.
public class UserProfile { public UserProfile(Address address) { HomeAddress = address ?? throw new ArgumentNullException(nameof(address)); } public Address HomeAddress { get; } // Read-only property } // Использование var user = new UserProfile(new Address { City = "Moscow" }); // HomeAddress никогда не будет null.Главный вывод: Публичные поля нарушают инкапсуляцию. Состояние объекта должно контролироваться самим объектом, а клиентский код должен быть защищен от работы с объектом в невалидном состоянии (например, с
null-ссылками).