【问题标题】:Boxing/Unboxing and Nullable?装箱/拆箱和可空?
【发布时间】:2008-12-17 14:56:04
【问题描述】:

我知道装箱和拆箱是关于强制转换(真实类型到对象...对象到真实类型)。但我不明白 MSDN 对 Nullable 的看法。这是我看不懂的文字:

当可空类型被装箱时,公共语言运行时会自动装箱 Nullable 对象的基础值,而不是 Nullable 对象本身。也就是说,如果 HasValue 属性为 true,则 Value 属性的内容被装箱。当可空类型的基础值被拆箱时,公共语言运行库会创建一个初始化为基础值的新 Nullable 结构。 Source

当您将对象更改为真实类型时,可以为空的真实类型变量将是对象的类型?没看懂?

【问题讨论】:

  • 伟大的思想都一样。 (参见@Jon 和@Marc)
  • 伟大的头脑需要从 SO 休假 :)

标签: .net nullable


【解决方案1】:

它的意思是,如果你这样做:

int? x = 5;
object y = x; // Boxing

您最终会得到一个盒装的int,而不是盒装的Nullable<int>。同样,如果你这样做:

int? x = null; // Same as new Nullable<int>() - HasValue = false;
object y = x; // Boxing

然后 y 最终成为一个空引用。

【讨论】:

  • @Jon 在第二种情况下,没有装箱,文档很清楚。它只是分配一个空引用。只有当HasValue 标志为真(非空值)时,底层值类型才会被装箱。关于你最终得到一个盒装的int,而不是盒装的Nullable&lt;int&gt;,我自己也有误解。
  • @nawfal:它分配了一个空引用,但这是一个产生空引用的装箱操作。查看生成的 IL(我刚刚仔细检查过)——它使用了 box 指令。 “装箱操作”和“返回装箱值的操作”IMO之间存在差异。您指的是哪个文档?
  • @JonSkeet msdn.microsoft.com/en-us/library/ms228597.aspx 我引用:基于可空类型的对象仅在对象非空时才被装箱。如果 HasValue 为 false,则将对象引用分配给 null 而不是装箱。
  • @nawfal:我用 C# 规范第 4.3.1 节反驳:“如果它是空值,则将可空类型的值装箱会产生空引用。”我认为认为它仍然是一个拳击操作是有道理的——只是一个不创建盒子的操作。就像一个强制转换操作即使在执行时失败仍然是一个强制转换操作。
  • @JonSkeet 那是一些信息。谢谢,会努力记住的! :) 你能看到这个问题吗:stackoverflow.com/questions/20655473/…。感觉会很有趣.. :)
【解决方案2】:

这意味着如果你这样做:

int? i = 5;
object o = i;

这是一个装箱的“int”(5),而不是“int?” (5)。如果 x 为 null (!HasValue),则 o 将为 null,而不是围绕空“int?”的框

然后当你拆箱时:

i = (int?)o;

如果 o 为 null,则 i 变为空的 "int?";否则,将 5 拆箱并用于创建“new int?(5)”。

基本上,您不应该(除了作弊)能够直接获得盒装的nullable&lt;T&gt; - 只有盒装的T

【讨论】:

  • " 如果 x 为 null " 应该是 " If i had been null "... x 变量在 JonSkeet 示例中...您使用了 i。
  • 请注意,Jon 将他的答案发布了一半,所以他会得到最旧的答案。所以他们是平的。
  • 哈哈!!我保证,这一切都是独立的——即使是 x 也纯属巧合。不,说真的!
  • @mackenir:实际上发布到一半是在编码时尝试使用制表符的结果。我点击了tab-return,它发布了答案。我最生气了:(
【解决方案3】:

如果Nullable&lt;T&gt;null,它将被装箱为空引用,并且不会作为HasValue = true 的装箱值类型。

实际上,要实现此功能,需要 CLR 本质上支持Nullable&lt;T&gt; 类型并区别对待。开发人员不能编写自己的类型,像Nullable&lt;T&gt;

值得注意的是,这是 .NET 2.0 后期的功能之一。在早期的测试版中,Nullable&lt;T&gt; 的行为就像一个正常的结构。在最终版本中,它被更改为 box to null 引用。此更改对 SQL Server CLR 团队来说是特别重大的,他们必须为此更改一些基本内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    • 2013-08-25
    • 2012-07-15
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    相关资源
    最近更新 更多