为什么Nullable <t>被认为是值类型?</t>

时间:2010-01-08 21:51:58

标签: .net nullable

您是否曾尝试使用Convert.ChangeType()方法将值转换为Nullable<T>类型?尴尬的是,它会抛出一个InvalidCastException说“Null对象无法转换为值类型”。

尝试在即时窗口中运行此操作:?System.Convert.ChangeType(null, typeof(int?))

由于某些不明原因,Nullables被视为价值类型。例如,typeof(int?).IsValueType会返回true

对我而言,由于Nullable<T>接受null,它是类类型,而不是值类型。有谁知道为什么会以不同的方式实施?

4 个答案:

答案 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),但是从nullNullable<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与参考不同 - 实际上我们的分歧是我们选择使用哪种抽象级别的问题。