您是否曾尝试使用Convert.ChangeType()
方法将值转换为Nullable<T>
类型?尴尬的是,它会抛出一个InvalidCastException
说“Null对象无法转换为值类型”。
尝试在即时窗口中运行此操作:?System.Convert.ChangeType(null, typeof(int?))
由于某些不明原因,Nullables被视为价值类型。例如,typeof(int?).IsValueType
会返回true
。
对我而言,由于Nullable<T>
接受null
,它是类类型,而不是值类型。有谁知道为什么会以不同的方式实施?
答案 0 :(得分:29)
System.Nullable<T>
在技术上是一个结构,所以它是一个值类型(null
的{{1}}值与空引用不完全相同。它是一个布尔标志,表示缺少一个值。)但是,它被运行时特别处理,这使它成为一种笨拙的值类型。首先,它不满足Nullable<T>
类型约束(它也不满足where T : struct
,因为它的价值。其次,它表现出一种有趣的拳击行为。拳击where T : class
将导致:
Nullable<T>
引用,如果值为null
。基础类型的盒装值,如果它实际包含值。也就是说,在声明中:
null
int? x = 2;
object y = x;
不是盒装y
。它只是一个盒装Nullable<int>
。您可以将int
类型的任何盒装值解包到T
(当然还有Nullable<T>
)。将T
引用转换为null
会产生Nullable<T>
值(如您所料)。
运行时的这种特殊处理使得可空类型的工作方式与null
在引用类型中的工作方式更相似。
答案 1 :(得分:12)
Nullable<T>
是一个值类型(它是一个结构,请参阅MSDN documentation),但是从null
到Nullable<T>
的隐式转换没有值( x.HasValue == false
)。还存在从类型T
的值到类型Nullable<T>
的值的隐式转换。
此外,所有操作符都从常规类型中解除,直接使用可空类型。
答案 2 :(得分:1)
Nullable<T>
作为结构实现,结构是值类型。
答案 3 :(得分:1)
我刚刚在Why Nullable<T> is a struct?的“相关问题”列表中看到了这个问题,我认为我的答案也适用于此。 Nullable<T>
的重点是在每个方面都像一个值类型,除了获取空值的能力。
可以通过两种方式查看空引用的null。一个是它没有引用任何东西,另一个是它没有任何有意义的价值。这些东西有两种不同的方式来说同样的东西,但它们有不同的用途。
Nullable<T>
使我们能够说“这没有任何有意义的值”,并且在某种程度上它可以具有与空引用相同的语义,但它不像任何其他方式的引用。当null时,它的nullity纯粹是“没有意义的值”null - 而不是“不引用任何东西”,当不为null时它保持一个值,而不是指它。
(Aaronaught认为这意味着Nullable不能真正包含null,而我不同意,因为在它使用它的级别上可以有一个语义null,他的观点值得考虑,因为即使“null”可以为Nullable与参考不同 - 实际上我们的分歧是我们选择使用哪种抽象级别的问题。