Почему люди используют магические значения вместо нуля в своем коде? - PullRequest
9 голосов
/ 26 февраля 2009

Я видел это в устаревшем коде и в некоторых проектах с открытым исходным кодом .NET. Я не могу представить причину сделать это. Мне просто гораздо проще использовать «ноль».

Пример:

public class Category
{
   int parentID;

   bool HasParent
   {
      get
      {
          return parentID != -1;
      }
   }
}

против

public class Category
{
   int parentID;

   bool HasParent
   {
      get
      {
          return parentID != null;
      }
   }
}

Ответы [ 6 ]

11 голосов
/ 26 февраля 2009

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

Employee employee = Employees.Find("John Smith");
if(employee == null) throw new Exception("Employee not found");

Проблема возникает при использовании типов value , таких как int, char или float. В отличие от ссылочных типов, которые указывают на блок данных где-то еще в памяти, эти значения хранятся и обрабатываются внутри (нет указателя / ссылки).

Из-за этого по умолчанию типы значений не имеют нулевого значения . В предоставленном вами коде невозможно для parentID быть нулевым (на самом деле я удивлен, что это даже получено вашим компилятором - Visual Studio 2008 и, вероятно, 2005 будут рисовать зеленое подчеркивание и сообщать, что утверждение всегда ложно).

Чтобы int имел нулевое значение, вы должны объявить его как nullable

int? parentID;

Теперь parentID может содержать нулевое значение, потому что теперь это указатель (хорошо "ссылка") на 32-разрядное целое число вместо 32-разрядного целого числа.

Так что, надеюсь, вы понимаете, почему «магические значения» часто используются для представления нулей с помощью базовых типов (типов значений). Это просто большая проблема, и часто большой удар по производительности (посмотрите, что такое бокс / распаковка), чтобы сохранить эти типы значений как ссылку на значение, чтобы они могли быть нулевыми.

Изменить: Для получения дополнительной информации о боксе / распаковке (что вам нужно иметь int == ноль), см. Статью в MSDN :

Бокс и распаковка (Руководство по программированию в C #)

Производительность

По отношению к простым назначениям упаковка и распаковка являются вычислительно дорогостоящими процессами. Когда тип значения упакован, новый объект должен быть выделен и создан. В меньшей степени, бросок, требуемый для распаковки, также дорог в вычислительном отношении. Для получения дополнительной информации см. Производительность.

4 голосов
/ 26 февраля 2009

Это часто привычки, разработанные при программировании на Си. Многие программисты на Си были бы потрачены впустую из-за пустых целых чисел, которые, по крайней мере, требуют всего дополнительного бита и, возможно, даже указателя. Это особенно плохо, когда вы знаете, что значение будет положительным, и у вас есть все пространство отрицательных значений, которое можно использовать для флагов. -1 может означать, что не установлен, -2 может означать, что parentId даже не имеет смысла в контексте этого узла, -3 может означать, что у узла был родитель, который не мог справиться с работой, и его оставили в выпивке, и больше никогда не видел и т.д ...

В мире C # чистота обнуляемых целочисленных значений (и их простая интеграция с RDMS) вместе с компьютерами с 2 ГБ ОЗУ означает, что старые привычки C медленно умирают, а старые привычки умирают тяжело.

3 голосов
/ 26 февраля 2009

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

Это может быть критично для языков или приложений, которые плохо обрабатывают исключения.

2 голосов
/ 26 февраля 2009

Работая с большими хранилищами данных, я иногда использую значение 0 вместо нуля, чтобы вставить ненулевое значение в мой куб. У меня всегда есть идентификатор 0, соответствующий значению «Неизвестно» во всех измерениях, поэтому у меня есть куб без нулевых значений.

главный интерес в нем - иметь более простые и эффективные запросы

1 голос
/ 26 февраля 2009

Типы значений Nullable доступны не на всех языках / средах; Они были добавлены в .Net 2.0. Если ваш унаследованный код основан на .Net и был запущен с использованием инфраструктуры 1.1, то вы ответили, что в то время ноль не был опцией.

0 голосов
/ 26 февраля 2009

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

...