分配bool?布尔

时间:2013-11-20 04:34:44

标签: c# .net compiler-construction nullable

请考虑以下代码:

bool x;
bool? y = null;
x = y?? true;

bool?分配给bool是一个编译时错误,但上面的代码在编译和运行时都成功。为什么?虽然第3个语句确保我们永远不会将null分配给x,但如果y不为空,我们仍然会将bool?分配给bool,所以它应该是编译器的POV错误,不是吗?

或者C#编译器是否足够聪明,发现特定的代码片段可能无法创建null分配给x的情况?

3 个答案:

答案 0 :(得分:2)

此表达式的类型:

y ?? true

bool,而不是bool?

来自C#5规范的第7.13节:

  

表达式a ?? b的类型取决于操作数上可用的隐式转换。按优先顺序,a ?? b的类型是A 0 ,A或B,其中A是a的类型(假设a有类型),B是类型b(假设b具有类型),如果A是可空类型,则A 0 是A的基础类型,否则为A.具体而言,a ?? b按如下方式处理:

     
      
  • 如果A存在且不是可空类型或引用类型,则会发生编译时错误。
  •   
  • 如果b是动态表达式,则结果类型是动态的。在运行时,首先评估a。如果a不为空,则a将转换为动态,这将成为结果。否则,将评估b,这将成为结果。
  •   
  • 否则,如果A存在并且是可空类型并且存在从b到A 0 的隐式转换,则结果类型为A 0 。在运行时,首先评估a。如果a不为空,则将a解包为类型A 0 ,这将成为结果。否则,b将被评估并转换为类型A 0 ,这将成为结果。
  •   
  • 否则,如果A存在并且从b到A存在隐式转换,则结果类型为A.在运行时,首先评估a。如果a不为空,则a成为结果。否则,b将被评估并转换为类型A,这将成为结果。
  •   
  • 否则,如果b具有类型B并且从a到B存在隐式转换,则结果类型为B.在运行时,首先评估a。如果a不为null,则将a解包为类型A 0 (如果A存在且可为空)并转换为类型B,这将成为结果。否则,b将被评估并成为结果。
  •   
  • 否则,ab不兼容,并发生编译时错误。
  •   

在你的情况下,我们在第三个子弹中:

  • A是bool?
  • 0 bool
  • B是bool

...所以结果类型为bool,您可以将其分配给bool类型的变量。

答案 1 :(得分:1)

bool x;
bool? y = null;
x = y?? true;

y ?? truey.HasValue ? y.GetValueOrDefault() : true的语法糖。所以你真的在编译器的POV中分配bool。看一下生成的IL,看看C#语言的功能背后发生了什么。

看看ILDasm。玩它会教你很多语言!

答案 2 :(得分:0)

请参阅此链接上的备注部分,您可以知道原因: http://msdn.microsoft.com/en-us/library/vstudio/ms173224.aspx

  

可空类型可以包含值,也可以是未定义的。 ?? ??   operator定义了可空类型时要返回的默认值   被分配给非可空类型