Причина, по которой вы не всегда должны использовать обнуляемые типы, заключается в том, что иногда вы можете гарантировать, что значение будет инициализировано. И вы должны попытаться спроектировать свой код так, чтобы это происходило как можно чаще. Если нет никакого способа, которым значение может быть неинициализировано, то нет причины, по которой для него должно быть допустимое значение null. В качестве очень простого примера рассмотрим это:
List<int> list = new List<int>()
int c = list.Count;
Это всегда действительно. Невозможно не инициализировать c
. Если бы он был превращен в int?
, вы бы фактически сказали читателям кода: «это значение может быть нулевым. Обязательно проверьте, прежде чем использовать его». Но мы знаем, что этого никогда не произойдет, так почему бы не предоставить эту гарантию в коде?
Вы абсолютно правы в случаях, когда значение является необязательным. Если у нас есть функция, которая может возвращать или не возвращать строку, верните ноль. Не возвращайте string.Empty (). Не возвращайте «магические ценности».
Но не все значения являются необязательными. А если сделать все необязательным, остальной код становится намного сложнее (добавляется еще один путь к коду, который необходимо обработать).
Если вы можете конкретно гарантировать, что это значение всегда будет действительным, тогда зачем выбрасывать эту информацию? Это то, что вы делаете, делая это обнуляемым типом. Теперь значение может существовать или не существовать, и любой, кто использует значение, должен будет обрабатывать оба случая. Но вы знаете, что только один из этих случаев возможен в первую очередь. Поэтому сделайте пользу пользователям вашего кода и отразите этот факт в своем коде. Любые пользователи вашего кода могут рассчитывать на то, что значение является действительным, и им нужно обрабатывать только один случай, а не два.