Почему null не допускается для DateTime в C#?
, Почему нельзя присвоить значение null типа datetime в C#? Как это было реализовано? И можно ли использовать эту функцию, чтобы сделать ваши собственные классы ненулевыми?
Пример:
string stringTest = null; // Okay
DateTime dateTimeTest = null; // Compile error
Я знаю, что я могу использовать DateTime?
в C# 2.0, чтобы разрешить значение null, чтобы быть отнесены к dateTimeTest и что я могу использовать Джон Скит это никогда не принимало класс на мои строки, чтобы получить время выполнения ошибка о присвоении stringTest. Мне просто интересно, почему эти два типа ведут себя по-разному.
6 ответов:
DateTime
является типом значения (struct
), где-As string является типом ссылки (class
и т. д.). В этом и заключается ключевое отличие. Ссылка всегда может быть нулевой; значение не может (если только оно не используетNullable<T>
- то естьDateTime?
), хотя оно может быть нулевым (DateTime.MinValue
), что часто интерпретируется как то же самое, что и null (esp. в 1.1).
DateTime-это структура, а не класс. Сделайте "перейти к определению" или посмотрите на него в обозревателе объектов, чтобы увидеть.
ХТ!
Важное различие между типами значений и ссылочными типами состоит в том, что типы значений имеют такую "семантику значений". DateTime, Int32 и все другие типы значений не имеют идентичности, Int32 "42" по существу неотличим от любого другого Int32 с тем же значением.
Все значения типа "objects" существуют либо в стеке, либо в составе объекта ссылочного типа. Одним из особых случаев является приведение экземпляра типа значения к объекту или интерфейсу - это называется "бокс", и он просто создает фиктивный объект ссылочного типа, содержащий только то значение, которое может быть извлечено обратно ("распаковано").
Ссылочные типы, с другой стороны, имеют идентичность. "новый объект () "не равен никакому другому" новому объекту ()", потому что они являются отдельными экземплярами в куче GC. Некоторые ссылочные типы предоставляют метод Equals и перегруженные операторы, чтобы они вели себя более ценностно, например. строка " abc "равна другой строке "abc", даже если они на самом деле являются двумя различными объектами.
Итак при наличии ссылки она может содержать либо адрес допустимого объекта, либо значение null. Когда объекты типа value все-ноль, они просто равны нулю. Напр.. целочисленный ноль, плавающий ноль, логическое значение false или DateTime.Параметр minvalue. Если вам нужно различать "ноль" и "значение отсутствует / null", вам нужно использовать либо отдельный логический флаг, либо, еще лучше, использовать класс Nullable
в .NET 2.0. Это просто значение плюс логический флаг. Есть также поддержка в CLR, так что бокс из Nullable с HasValue=false приводит к нулевой ссылке, а не к коробочной структуре с false+zero, как это было бы, если бы вы реализовали эту структуру самостоятельно.
DateTime-это тип значения, такой же, как int. Только ссылочные типы (такие как string или MyCustomObject) могут иметь значение null. Ссылочные типы действительно хранят "ссылки"на расположение объектов в куче.
Вот статья , которую я нашел, которая объясняет это лучше. а вот статья MSDN об этом
Для того, чтобы тип значения был null, должно существовать некоторое значение, которое он может содержать, которое не имело бы никакого другого законного значения, и которое система каким-то образом узнает, должно рассматриваться как "null". Некоторые типы значений могут удовлетворять первому критерию, не требуя дополнительного хранения. Если бы .net был разработан с нуля с концепцией нулевых значений в виду, он мог бы иметь
К тому времени, когда было решено обеспечить поддержку типов значений nullable в .net framework 2.0, однако, было написано много кода, который предполагал, что значения по умолчанию для таких вещей, какObject include a virtual
IsLogicalNullproperty, and a non-virtual
IsNullwhich would return
trueif
thisis null and, otherwise invoke its
IsLogicalNullproperty and return the result. If .net had done this, it would have avoided the need for the quirky boxing behavior and
structconstraint of
Nullable(an empty
Nullablecould be boxed as an empty
Nullable, and still be recognized as
null`).Guid
иDateTime
, не будут рассматриваться какnull
. Поскольку большая часть значения в nullable типах лежит с их предсказуемым значением по умолчанию (т. е.null
), имеющие типы который имел значениеnull
, но по умолчанию перешел на что-то другое, что добавило бы больше путаницы, чем ценности.