Подтвердить что ты не робот

Почему я не должен всегда использовать типы с нулевым значением в С#

Я искал некоторые хорошие рекомендации по этому поводу, поскольку концепция была введена в .net 2.0.

Зачем мне когда-либо хотеть использовать непустые типы данных в С#? (Лучше вопрос, почему бы мне не выбирать типы с нулевым значением по умолчанию и использовать только типы, не допускающие нулевой, если это явно имеет смысл.)

Есть ли "значительная" производительность, связанная с выбором типа данных с нулевыми значениями по сравнению с неэлементным равноправным узлом?

Я предпочитаю проверять свои значения на null вместо Guid.empty, string.empty, DateTime.MinValue, <= 0 и т.д. и работать с общими типами в целом. И единственная причина, по которой я чаще не выбираю типы с нулевыми значениями, - это зудящее чувство в затылке, что заставляет меня чувствовать себя более чем обратную совместимость, которая заставляет лишний "?" символ, чтобы явно разрешить нулевое значение.

Есть ли кто-нибудь, который всегда (чаще всего) выбирает типы с нулевым значением, а не типы с нулевым значением?

Спасибо за ваше время,

4b9b3361

Ответ 1

Причина, по которой вы не всегда должны использовать типы с нулевым значением, заключается в том, что иногда вы можете гарантировать, что значение будет инициализировано. И вы должны попытаться разработать свой код, чтобы это было так часто, насколько это возможно. Если нет никакого способа, чтобы значение могло быть неинициализировано, тогда нет причин, по которым нуль должен быть юридическим значением для него. В качестве очень простого примера рассмотрим следующее:

List<int> list = new List<int>()
int c = list.Count;

Это всегда справедливо. Нет никакого способа, чтобы c мог быть неинициализирован. Если бы он был превращен в int?, вы бы действительно рассказывали читателям код "это значение может быть нулевым. Обязательно проверьте, прежде чем использовать его". Но мы знаем, что этого никогда не может быть, поэтому почему бы не разоблачить эту гарантию в коде?

Вы абсолютно правы в случаях, когда значение является необязательным. Если у нас есть функция, которая может возвращать строку или не возвращать ее, верните нуль. Не возвращайте string.Empty(). Не возвращайте "магические значения".

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

Если вы можете специально гарантировать, что это значение всегда будет действительным, то зачем выбрасывать эту информацию? Это то, что вы делаете, делая его нулевым типом. Теперь значение может или не может существовать, и любой, кто использует значение, должен будет обрабатывать оба случая. Но вы знаете, что только один из этих случаев возможен в первую очередь. Так что пользователи вашего кода пользуются услугой и отражают этот факт в вашем коде. Любые пользователи вашего кода могут затем полагаться на допустимое значение, и они должны обрабатывать только один случай, а не два.

Ответ 2

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

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

// nice and simple, this will always work
int a = myInt;

// compiler won't let you do this
int b = myNullableInt;

// compiler allows these, but causes runtime error if myNullableInt is null
int c = (int)myNullableInt;
int d = myNullableInt.Value;    

// instead you need to do something like these, cumbersome and less readable
int e = myNullableInt ?? defaultValue;
int f = myNullableInt.HasValue ? myNullableInt : GetValueFromSomewhere();

Ответ 3

У вас, похоже, есть два разных вопроса...

Зачем мне когда-либо хотеть использовать типы с нулевыми значениями в С#?

Простой, потому что данные типа значения, на которые вы полагаетесь, гарантированы компилятором, чтобы на самом деле иметь значение!

Почему бы мне не выбрать типы с нулевым значением по умолчанию и использовать только типы с нулевым значением, если это явно имеет смысл?

Как уже упоминал Джоэл, тип может быть только нулевым, если он является ссылочным типом. Значения типов гарантируются компилятором, чтобы иметь значение. Если ваша программа зависит от переменной, чтобы иметь значение, то это поведение, которое вам нужно, не выбирая тип с нулевым значением.

Конечно, когда ваши данные поступают откуда угодно, это не ваша программа, тогда все ставки отключены. Лучший пример - из базы данных. Поля базы данных могут быть null, поэтому вы хотите, чтобы ваша программная переменная имитировала это значение, а не просто создать "магическое" значение (т.е. -1, 0 или что-то еще), которое "представляет" null. Вы делаете это с помощью типов с нулевым значением.

Ответ 4

Я думаю, что разработчики языка считают, что "ссылочные типы, являющиеся нулевыми по умолчанию", были ошибкой, и что не-nullable является единственным разумным дефолтом, и вам следует отказаться от nullness. (Так это во многих современных функциональных языках.) "Null" обычно представляет собой кучу проблем.

Ответ 5

Я стараюсь использовать типы Nullable везде, где они имеют смысл - я не буду заботиться о производительности до тех пор, пока это не проблема, тогда я исправлю несколько областей, где это необходимо, и сделайте с ними.

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

Ответ 6

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

Значения NULL предпочитают многие разработчики баз данных и программисты базы данных SQL, но с небольшим изменением в мышлении о проблеме вы можете избавиться от нулевых значений и на самом деле иметь более простой и надежный код (например, не беспокоиться о NullReferenceException s).

На самом деле большой спрос на "T!" оператор, который делает любой ссылочный тип недействительным, подобно тому, как "T?" делает типы значений нулевыми, и Андерс Хейлсберг, изобретатель С#, пожелал, чтобы он включил эту способность.

См. также вопрос Почему "null" присутствует в С# и java?

Ответ 7

Единственный раз, когда должен использоваться Nullable Type, является то, что определенное поле в таблице базы данных абсолютно требует, чтобы в какой-то момент приложение было отправлено или получено. Даже в таком случае всегда нужно пытаться найти способ использования Nullable Type. Бул не всегда ваш лучший друг.