为什么 C# 中的 DateTime 不允许为 null?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/689512/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is null not allowed for DateTime in C#?
提问by Jan Aagaard
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?
为什么不允许在 C# 中为 DateTime 分配 null?这是如何实施的?并且可以使用此功能使您自己的类不可为空吗?
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 classon my string to get a run time error on the assignment of stringTest. I'm just wondering why the two types behave differently.
我知道我可以DateTime?
在 C# 2.0 中使用以允许将 null 分配给 dateTimeTest,并且我可以在我的字符串上使用Jon Skeet 的 NonNullable 类来获取有关 stringTest 分配的运行时错误。我只是想知道为什么这两种类型的行为不同。
采纳答案by Marc Gravell
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
是值类型 ( struct
),其中字符串是引用类型 (class
等)。这是关键的区别。引用始终可以为空;一个值不能(除非它使用Nullable<T>
- ie DateTime?
),尽管它可以是 zero'd ( DateTime.MinValue
),这通常被解释为与 null 相同的东西(尤其是在 1.1 中)。
回答by Simon
DateTime is a struct and not a class. Do a 'go to definition' or look at it in the object browser to see.
DateTime 是一个结构而不是一个类。执行“转到定义”或在对象浏览器中查看以查看。
HTH!
哼!
回答by danswain
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.
DateTime 是值类型,与 int 相同。只有引用类型(如字符串或 MyCustomObject)可以为 null。引用类型真正存储对堆上对象位置的“引用”。
here's a articleI found that explains it better. and here's the MSDN article on it
回答by Rob Haupt
string is a class whereas DateTime is a structure. Thats why you cannot set it to null
string 是一个类,而 DateTime 是一个结构。这就是为什么你不能将它设置为 null
回答by Rob Haupt
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.
ValueTypes 和引用类型之间的重要区别在于值类型具有这些“值语义”。DateTime、Int32 和所有其他值类型都没有标识,Int32 "42" 基本上与具有相同值的任何其他 Int32 没有区别。
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.
另一方面,引用类型具有标识。“new Object()”不等于任何其他“new Object()”,因为它们是 GC 堆上的独立实例。一些引用类型提供 Equals 方法和重载运算符,以便它们的行为更像值,例如。字符串“abc”等于其他“abc”字符串,即使它们实际上是两个不同的对象。
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.
因此,当您有一个引用时,它可以包含有效对象的地址,也可以为空。当值类型对象全为零时,它们只是零。例如。整数零、浮点零、布尔值 false 或 DateTime.MinValue。如果需要区分“零”和“值缺失/空”,则需要使用单独的布尔标志,或者更好的是,使用 .NET 2.0 中的 Nullable<T> 类。这只是值加上布尔标志。在 CLR 中也有支持,因此使用 HasValue=false 对 Nullable 进行装箱会导致空引用,而不是在带有 false+0 的装箱结构中,就像您自己实现此结构一样。
回答by supercat
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`).
对于 null 值类型,必须有一些它可以持有的值,该值没有其他合法含义,并且系统会以某种方式知道应该将其视为 "null"。某些值类型可以满足第一个标准而无需任何额外存储。如果 .net 在设计时就考虑了可空值的概念,那么它可能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`)。
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.
然而,当决定在 .net framework 2.0 中提供对可空值类型的支持时,已经编写了大量代码,它们假定诸如Guid
和 之类的东西的默认值DateTime
不会被视为null
. 由于可空类型中的大部分值与其可预测的默认值(即null
)有关,因此具有具有null
值但默认为其他值的类型会比值增加更多的混乱。