示例:
string stringTest = null; // Okay
DateTime dateTimeTest = null; // Compile error
我知道在C# 2.0中可以使用DateTime?
来允许将null分配给dateTimeTest,并且我可以在字符串上使用Jon Skeet的NonNullable类,以在分配stringTest时获取运行时错误。我只是想知道这两种类型为什么表现不同。
string stringTest = null; // Okay
DateTime dateTimeTest = null; // Compile error
我知道在C# 2.0中可以使用DateTime?
来允许将null分配给dateTimeTest,并且我可以在字符串上使用Jon Skeet的NonNullable类,以在分配stringTest时获取运行时错误。我只是想知道这两种类型为什么表现不同。
DateTime
是一个值类型(struct
),而字符串是一个引用类型(class
等)。 这是它们之间的关键区别。 引用可以始终为null; 值不能(除非它使用Nullable<T>
- 即DateTime?
),尽管它可以被赋为零(DateTime.MinValue
),这经常被解释为与null相同的东西(特别是在1.1版本中)。
DateTime是一个结构体而不是类。可以通过“转到定义”或在对象浏览器中查看它。
希望对你有所帮助!
DateTime是一个值类型,与int一样。只有引用类型(如字符串或MyCustomObject)才可以为空。引用类型实际上存储了指向堆上对象位置的"引用"。
这里有一篇文章,讲解得更清楚。而这里是MSDN关于此的文章
对于值类型来说,要使其为null,必须有一些它可以持有的值,这些值没有其他合法的含义,并且系统会以某种方式知道应该将其视为“null”。一些值类型可以满足第一个条件而不需要任何额外的存储空间。如果.net从一开始就考虑了可空值的概念,它可能会在Object中包含一个虚拟的IsLogicalNull属性和一个非虚拟的IsNull属性,如果this为null,则返回true,否则调用其IsLogicalNull属性并返回结果。如果.net这样做,就可以避免需要奇怪的装箱行为和Nullable的结构约束(一个空的Nullable可以被装箱为一个空的Nullable,并仍然被识别为null)。
到决定在 .NET Framework 2.0 中为可空值类型提供支持的时候,很多代码已经编写了,这些代码假定像Guid
和 DateTime
这样的默认值不会被视为 null
。由于可为空类型的很多价值都在于它们可预测的默认值(即 null
),因此拥有一个可以具有 null
值但默认为其他值的类型,可能会增加更多混乱而不是价值。string是一个类,而DateTime是一个结构。这就是为什么你不能将其设置为null的原因。