C# if条件内隐式可为null的强制转换
我最近发现一些代码具有如下可空C# if条件内隐式可为null的强制转换,c#,casting,nullable,C#,Casting,Nullable,我最近发现一些代码具有如下可空if条件: bool? nullableVariable; //some lines of code involving nullableVariable if (nullableVariable == true) { //some other lines of code } 乍一看,我认为它可能容易出现异常。我的意见基于以下事实: bool? nullableVariable = null; bool variable = (bool)nullableV
if
条件:
bool? nullableVariable;
//some lines of code involving nullableVariable
if (nullableVariable == true)
{
//some other lines of code
}
乍一看,我认为它可能容易出现异常。我的意见基于以下事实:
bool? nullableVariable = null;
bool variable = (bool)nullableVariable
将引发错误System.InvalidOperationException:“Nullable对象必须有一个值。”我希望在if(nullableVariable==true)
语句中执行从bool?
到bool
的左操作数转换(在=
操作符上移动光标会导致Visual Studio提示bool bool.operator==(bool left,bool right),这一事实证实了我的印象)
有鉴于此,我惊讶地发现:
bool? nullableVariable = null;
if (nullableVariable == true)
{
//some other lines of code
}
不会引发异常(跳过括号内的代码)
所以问题是:if
语句内部发生了什么?可能是隐藏的try-catch
将左操作数从bool?
转换为bool
,并将结果设置为false?或者可能是右操作数从bool
转换为bool?
?或者其他什么?参见
简而言之,它们被重载以进行比较,如==
:
对于相等运算符==,如果两个操作数都为空,则结果为空
如果只有一个操作数为null,则结果为false;
否则,将比较包含的操作数值
因此,通过与true
或false
进行比较,可以避免处理可空值为null
的情况,这使得代码更具可读性,如示例中所示:
if (nullableVariable == true)
{
//some other lines of code
}
因此,每当您将(=
或!=
)一个bool?
与一个bool
进行比较时,结果不是一个bool?
(或null
),而是一个bool
与上面链接中描述的规则进行比较。这就是为什么您可以在if
中使用它的原因,请参见
简而言之,它们被重载以进行比较,如==
:
对于相等运算符==,如果两个操作数都为空,则结果为空
如果只有一个操作数为null,则结果为false;
否则,将比较包含的操作数值
因此,通过与true
或false
进行比较,可以避免处理可空值为null
的情况,这使得代码更具可读性,如示例中所示:
if (nullableVariable == true)
{
//some other lines of code
}
因此,无论何时比较(
=
或!=
)一个bool?
与一个bool
时,结果都不是一个bool?
(或null
)但是使用上面链接中描述的规则的bool
。这就是为什么您可以在中使用它。如果
如其他人所述,相等运算符被提升为可为空的等价运算符
它的编译方式似乎有一些细微的差别。我不完全确定原因,但这可能与缺乏编译器知识有关,运算符是否会对复杂结构产生副作用,而像int
和bool
这样的类型则知道发生了什么
如果A
和B
是可空的
A==B
对于基本类型,如int
,这将编译为以下内容:
(A.GetValueOrDefault()==B.GetValueOrDefault())&&(A.HasValue==B.HasValue)
对于更复杂的类型:
(A.HasValue==B.HasValue)?!A.HasValue | |(A.GetValueOrDefault()==B.GetValueOrDefault())
如其他人所述,相等运算符被提升为可为空的等价运算符
它的编译方式似乎有一些细微的差别。我不完全确定原因,但这可能与缺乏编译器知识有关,运算符是否会对复杂结构产生副作用,而像int
和bool
这样的类型则知道发生了什么
如果A
和B
是可空的
A==B
对于基本类型,如int
,这将编译为以下内容:
(A.GetValueOrDefault()==B.GetValueOrDefault())&&(A.HasValue==B.HasValue)
对于更复杂的类型:
(A.HasValue==B.HasValue)?!A.HasValue | |(A.GetValueOrDefault()==B.GetValueOrDefault())