Почему null не допускается для DateTime в C #? - PullRequest
37 голосов
/ 27 марта 2009

Почему не разрешено присваивать нуль DateTime в C #? Как это было реализовано? И можно ли использовать эту функцию, чтобы сделать ваши собственные классы необнуляемыми?

Пример:

string stringTest = null; // Okay
DateTime dateTimeTest = null; // Compile error

Я знаю, что могу использовать DateTime? в C # 2.0, чтобы позволить null присваивать dateTimeTest, и что я могу использовать NonNullable класс Джона Скита в моей строке, чтобы получить ошибку времени выполнения в назначении из stringTest. Мне просто интересно, почему эти два типа ведут себя по-разному.

Ответы [ 6 ]

83 голосов
/ 27 марта 2009

DateTime - это тип значения (struct), где строка as - это ссылочный тип (class и т. Д.). Это ключевое отличие. Ссылка всегда может быть нулевой; значение не может (если оно не использует Nullable<T> - то есть DateTime?), хотя оно может быть равно нулю (DateTime.MinValue), что часто интерпретируется как то же самое, что и ноль (особенно в 1.1).

9 голосов
/ 27 марта 2009

DateTime - это структура, а не класс. Сделайте 'перейти к определению' или посмотрите на него в браузере объектов, чтобы увидеть.

НТН!

7 голосов
/ 27 марта 2009

Важное различие между ValueTypes и ссылочными типами состоит в том, что типы значений имеют эту "семантику значений". DateTime, Int32 и все другие типы значений не имеют идентичности, Int32 «42» по существу неотличим от любого другого Int32 с тем же значением.

Все значения типа "объекты" существуют либо в стеке, либо как часть объекта ссылочного типа. Один особый случай - когда вы приводите экземпляр типа значения к объекту или интерфейсу - это называется «боксом», и он просто создает фиктивный объект ссылочного типа, который содержит только значение, которое может быть извлечено обратно («распаковано») .

Типы ссылок, с другой стороны, имеют идентичность. «new Object ()» не равен никаким другим «new Object ()», потому что они являются отдельными экземплярами в куче GC. Некоторые ссылочные типы предоставляют метод Equals и перегруженные операторы, так что они ведут себя более как значения, например. Строка "abc" равна другой строке "abc", даже если на самом деле это два разных объекта.

Таким образом, когда у вас есть ссылка, она может содержать адрес действительного объекта или может быть нулевой. Когда объекты типа значения все ноль, они просто ноль. Например. целое число ноль, число с плавающей точкой, логическое значение false или DateTime.MinValue. Если вам необходимо различать «ноль» и «значение отсутствует / ноль», вам нужно использовать либо отдельный логический флаг, либо, что еще лучше, использовать класс Nullable в .NET 2.0. Это просто значение плюс логический флаг. В CLR также есть поддержка, так что бокс Nullable с HasValue = false приводит к пустой ссылке, а не в штучной структуре с false + ноль, как если бы вы реализовали эту структуру самостоятельно.

1 голос
/ 30 мая 2012

Чтобы тип значения был нулевым, должно быть какое-то значение, которое он может содержать, которое не имело бы другого законного значения, и , который система каким-то образом узнает, следует рассматривать как "нулевое" . Некоторые типы значений могут соответствовать первому критерию, не требуя дополнительного хранения. Если бы .net был спроектирован с нуля, имея в виду концепцию значений Nullable, он мог бы иметь Object include a virtual IsLogicalNull property, and a non-virtual IsNull which would return true if this is null and, otherwise invoke its IsLogicalNull property and return the result. If .net had done this, it would have avoided the need for the quirky boxing behavior and struct constraint of Nullable (an empty Nullable could be boxed as an empty Nullable , and still be recognized as null`).

К тому времени, когда было решено обеспечить поддержку типов значений NULL в .net Framework 2.0, однако, было написано много кода, который предполагал, что значения по умолчанию для таких вещей, как Guid и DateTime не будут рассматривается как null. Поскольку большая часть значений в обнуляемых типах лежит в их предсказуемом значении по умолчанию (то есть null), имеющем типы, которые имеют значение null, но по умолчанию устанавливаются на что-то другое, это добавило бы больше путаницы, чем значения.

1 голос
/ 27 марта 2009

DateTime - тип значения, такой же, как int. Только ссылочные типы (например, строка или MyCustomObject) могут быть нулевыми. В ссылочных типах действительно хранятся «ссылки» на расположение объектов в куче.

вот статья Я обнаружил, что это объясняет лучше. и вот статья MSDN

0 голосов
/ 27 марта 2009

строка - это класс, тогда как DateTime - это структура. Вот почему вы не можете установить его на ноль

...