Why it is not allowed to assign null to a DateTime in C#? How has this been implemented? And can this feature be used to make your own classes non-nullable?
Example:
string stringTest = null; // Okay
DateTime dateTimeTest = null; // Compile error
I know that I can use DateTime?
in C# 2.0 to allow null to be assigned to dateTimeTest and that I could use Jon Skeet's NonNullable class on my string to get a run time error on the assignment of stringTest. I'm just wondering why the two types behave differently.
DateTime
is a value-type (struct
), where-as string is a reference-type (class
etc). That is the key difference. A reference can always be null; a value can't (unless it uses Nullable<T>
- i.e. DateTime?
), although it can be zero'd (DateTime.MinValue
), which is often interpreted as the same thing as null (esp. in 1.1).
DateTime is a struct and not a class. Do a 'go to definition' or look at it in the object browser to see.
HTH!
The important distinction between ValueTypes and reference types is that value types have these "value semantics". A DateTime, Int32 and all other value types have no identity, an Int32 "42" is essentially indistinguishable from any other Int32 with the same value.
All value type "objects" exist either on stack or as a part of a reference type object. One special case is when you cast a value type instance to an Object or an interface - this is called "boxing", and it simply creates a dummy reference-type object which only contains the value that can be extracted back ("unboxed").
Reference types, on the other hand, have an identity. a "new Object()" does not equal any other "new Object()", because they are separate instances on the GC heap. Some reference types provide Equals method and overloaded operators so that they behave more value-like, eg. a String "abc" equals other "abc" String even if they are in fact two different objects.
So when you have a reference, it can either contain the address of a valid object, or it can be null. When value type objects are all-zero, they are simply zero. Eg. an integer zero, a float zero, Boolean false, or DateTime.MinValue. If you need to distinguish between "zero" and "value missing/null", you need to use either a separate Boolean flag, or, better yet, use the Nullable<T> class in .NET 2.0. Which is simply the value plus a Boolean flag. There's also support in the CLR so that boxing of a Nullable with HasValue=false results in a null reference, not in a boxed structure with false+zero, as it would if you were to implement this structure yourself.
DateTime is a value type, same as an int. Only reference types (like string or MyCustomObject) can be null. Reference types really store "references" to the objects location on the heap.
here's a article I found that explains it better. and here's the MSDN article on it
For a value-type to be null, there must be some value it can hold which would have no other legitimate meaning, and which the system will somehow know should be regarded as "null". Some value types could meet the first criterion without requiring any extra storage. If .net had been designed from the ground up with the concept of nullable values in mind, it could have had 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`).
By the time it was decided to provide support for nullable value types in .net framework 2.0, however, a lot of code had been written which assumed that the default values for things like Guid
and DateTime
would not be regarded as null
. Since much of the value in nullable types lies with their predictable default value (i.e. null
) , having types which had a null
value, but defaulted to something else, would have added more confusion than value.
string is a class whereas DateTime is a structure. Thats why you cannot set it to null
来源:https://stackoverflow.com/questions/689512/why-is-null-not-allowed-for-datetime-in-c