.net 装箱/拆箱和可空?

.net 装箱/拆箱和可空?,.net,nullable,.net,Nullable,我理解装箱和拆箱是关于强制转换(实类型到对象…对象到实类型)。但我不明白MSDN对Nullable的说法。以下是我不理解的文本: 当可空类型被装箱时,公共语言运行库会自动装箱可空对象的基础值,而不是可空对象本身。也就是说,如果HasValue属性为true,则Value属性的内容将被装箱。当可空类型的基础值解除绑定时,公共语言运行库将创建一个初始化为基础值的新的可空结构 将对象更改为实类型时,可为null的实类型变量将是对象的类型?我不明白?它说的是,如果你明白了: int? x = 5; ob

我理解装箱和拆箱是关于强制转换(实类型到对象…对象到实类型)。但我不明白MSDN对Nullable的说法。以下是我不理解的文本:

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


将对象更改为实类型时,可为null的实类型变量将是对象的类型?我不明白?

它说的是,如果你明白了:

int? x = 5;
object y = x; // Boxing
int? x = null; // Same as new Nullable<int>() - HasValue = false;
object y = x; // Boxing
int? i = 5;
object o = i;
最后得到的是一个装箱的
int
,而不是一个装箱的
可为空的
。同样,如果您这样做:

int? x = 5;
object y = x; // Boxing
int? x = null; // Same as new Nullable<int>() - HasValue = false;
object y = x; // Boxing
int? i = 5;
object o = i;
int?x=null;//与new Nullable()相同-HasValue=false;
对象y=x;//拳击

然后y作为空引用结束。

这意味着如果您执行以下操作:

int? x = 5;
object y = x; // Boxing
int? x = null; // Same as new Nullable<int>() - HasValue = false;
object y = x; // Boxing
int? i = 5;
object o = i;
装箱的是“int”(5),而不是“int?”(5)。如果x为null(!HasValue),那么o将为null,而不是围绕空“int”的框

然后,当您取消装箱时:

i = (int?)o;
如果o为null,则i变为空的“int”;否则,5将被取消绑定并用于创建“新int?(5)”

基本上,你不应该(除了作弊)直接得到一个装箱的
null
,只有装箱的
t

如果一个
null
null
,它将被装箱为null引用,并且不会作为带有
HasValue=true
的装箱值类型

事实上,为了实现这个特性,需要CLR本质上支持
Nullable
类型,并以不同的方式对待它。开发人员不能编写像
Nullable
那样工作的自己的类型


值得注意的是,这是.NET2.0晚期的一个特性。在早期beta中,
Nullable
的行为与正常结构一样。在最终版本中,它被更改为box to null reference。这一变化对SQL Server CLR团队来说是一个突破,他们必须为此改变一些基本的东西。

伟人所见略同。(cf@Jon和@Marc)伟大的头脑需要从SO开始休假:)“如果x是空的”应该是“如果我是空的”。。。x变量在JonSkeet示例中。。。你用过我。请注意,乔恩把他的答案贴了一半,这样他就能得到最早的答案。所以他们扯平了。哈哈!!我保证,这一切都是独立的——即使x是纯粹的巧合。不,说真的@麦肯尼:事实上,发布半成品是编码时尝试制表符的结果。我点击tabreturn,它发布了答案。我最恼火的是:(@Jon在第二种情况下,没有装箱,文档对此很清楚。它只分配了一个空引用。只有当
HasValue
标志为true时(非空值),基础值类型是装箱的。Spot on on about You以装箱的
int
,而不是装箱的
Nullable
,我自己也有误解。@nawfal:它分配了一个空引用,但这是一个装箱操作,它会产生一个空引用。查看生成的IL(我只是仔细检查了一下)-它使用的是
box
指令。“装箱操作”和“返回装箱值的操作”之间有区别IMO.您指的是哪些文档?@JonSkeet I quote:基于可空类型的对象只有在对象为非空时才被装箱。如果HasValue为false,则对象引用被指定为空而不是装箱。@nawfal:I使用C#规范第4.3.1节:“装箱一个可空类型的值,如果它是空值,则产生一个空引用。”我认为有意义的是,它仍然是一个拳击操作-只是一个不创建一个盒子。就像一个铸造操作仍然是一个铸造操作,即使它在执行时失败。@ Jon Switt是一些信息。谢谢,我会努力记住它!你能回答这个问题吗:。我觉得这会很有趣:)