分配布尔值?布尔

问题描述 投票:0回答:3

考虑以下代码:

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

bool?
分配给
bool
是编译时错误,但上述代码在编译时和运行时均成功。为什么?虽然第三条语句确保我们永远不会将
null
分配给
x
,但如果
y
不为空,我们仍然将
bool?
分配给
bool
,所以这应该是编译器POV的错误,没有?

或者 C# 编译器是否足够聪明,能够发现某段特定的代码不可能创建将

null
分配给
x
的情况?

c# .net nullable
3个回答
3
投票

该表达式的类型:

y ?? true

bool
,不是
bool?

摘自 C# 5 规范第 7.13 节:

表达式

a ?? b
的类型取决于操作数上可用的隐式转换。按照优先顺序,
a ?? b
的类型为A0、A或B,其中A是a的类型(假设a有一个类型),B是b的类型(假设b有一个类型)类型),如果 A 是可为 null 的类型,则 A0 是 A 的基础类型,否则是 A。具体来说,
a ?? b
的处理如下:

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

就您而言,我们处于第三个项目符号中:

  • A 是
    bool?
  • A0
    bool
  • B 是
    bool

...所以结果类型是

bool
,您可以将其分配给
bool
类型的变量。


1
投票

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

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

看看

ILDasm
。玩它会教你很多关于语言的知识!


0
投票

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

可空类型可以包含值,也可以是未定义的。这 ?? 运算符定义可空类型时要返回的默认值 被分配给不可为 null 的类型

© www.soinside.com 2019 - 2024. All rights reserved.