如何对布尔条件进行空合并?
How to null coalesce for Boolean condition?
我正在尝试安全地检查 IList<>
是否不为空。
var Foo = Bar.GimmeIListT(); // Returns an IList<SomeObject>
if (Foo?.Any())
// Do cool stuff with items in Foo
但是条件有误:
Cannot implicitly convert 'bool?' to 'bool'. An explicit conversion exists (are you missing a cast?)
看来条件的计算结果为可为空的布尔值,所以我尝试
if (Foo?.Any().Value())
但这也不好:
'bool' does not contain a definition for 'Value' and no extension .... blah blah blah
所以在第一个实例中它抱怨它是一个可为空的布尔值,但在第二个实例中它抱怨它不是。
作为我尝试的另一种途径:
if (Foo?.Any() == true)
这有效 - 但它不应该,因为它使用了第一条消息说它不需要的隐式转换!
这是怎么回事?正确的做法是什么?
用==
可以和bool?
对比一下,确实是best/simplest的做法:
if (Foo?.Any() == true) ...
至于为什么它在 if
中是不允许的,但是对于 ==
,Jon Skeet can explain 更好:
There's no implicit conversion from Nullable<bool>
to bool
. There is
an implicit conversion from bool
to Nullable<bool>
and that's what
happens (in language terms) to each of the bool constants in the first
version. The bool operator==(Nullable<bool>
, Nullable<bool>
) operator
is then applied. (This isn't quite the same as other lifted operators - the result is just bool
, not Nullable<bool>
).
In other words, the expression fred == false
is of type bool
,
whereas the expression fred
is of type Nullable<bool>
hence you
can't use it as the "if" expression.
所以 if
只允许 bool
而你有一个 bool?
,但是 ==
运算符将 bool
转换为 bool?
你可以比较两个 bool?
.
编辑:
看来 bool?
的原因是 Foo?.Any()
本身。如果你不想和true
比较,我建议你有临时变量:
bool? any = Foo?.Any();
if (any.Value) ...
或者,如果对象是 class,您可以使用 FirstOrDefault() != null
作为检查条件。它不会花时间,因为它只会得到第一个对象:
if (Foot?.FirstOrDefault() != null)...
虽然我会使用临时变量或 Foo?.Any() == true
选项。
原文:
注意:令我惊讶的是 if (a?.Any())
后面不能跟 .Value()
或 .Value
(!)。
我想你需要的是 Value
(属性) 没有 ()
(方法):
if (Foo?.Any()?.Value) ...
bool?
有 .Value
(属性) 这是 bool
.
Any()
returns bool
但是 Foo?.Any()
会 return bool?
因此 Foo?.Any().Value
不会编译,因为 Any()
return 是一个没有成员 Value
的 bool
。
如果Foo
是null
,Any()
将不会被执行,因为该语句将return null
不解释[=后面的部分23=]运算符。
但是如果你把 Foo?.Any()
放在括号中,你就可以使用类型 bool?
的结果并通过 Value
或 GetValueOrDefault()
检查它:
(Foo?.Any()).GetValueOrDefault()
更多语法糖,空合并运算符。 C# 8.0 或更高版本
if (Foo?.Any() ?? false) { }
我正在尝试安全地检查 IList<>
是否不为空。
var Foo = Bar.GimmeIListT(); // Returns an IList<SomeObject>
if (Foo?.Any())
// Do cool stuff with items in Foo
但是条件有误:
Cannot implicitly convert 'bool?' to 'bool'. An explicit conversion exists (are you missing a cast?)
看来条件的计算结果为可为空的布尔值,所以我尝试
if (Foo?.Any().Value())
但这也不好:
'bool' does not contain a definition for 'Value' and no extension .... blah blah blah
所以在第一个实例中它抱怨它是一个可为空的布尔值,但在第二个实例中它抱怨它不是。
作为我尝试的另一种途径:
if (Foo?.Any() == true)
这有效 - 但它不应该,因为它使用了第一条消息说它不需要的隐式转换!
这是怎么回事?正确的做法是什么?
用==
可以和bool?
对比一下,确实是best/simplest的做法:
if (Foo?.Any() == true) ...
至于为什么它在 if
中是不允许的,但是对于 ==
,Jon Skeet can explain 更好:
There's no implicit conversion from
Nullable<bool>
tobool
. There is an implicit conversion frombool
toNullable<bool>
and that's what happens (in language terms) to each of the bool constants in the first version. The bool operator==(Nullable<bool>
,Nullable<bool>
) operator is then applied. (This isn't quite the same as other lifted operators - the result is justbool
, notNullable<bool>
).In other words, the expression
fred == false
is of typebool
, whereas the expressionfred
is of typeNullable<bool>
hence you can't use it as the "if" expression.
所以 if
只允许 bool
而你有一个 bool?
,但是 ==
运算符将 bool
转换为 bool?
你可以比较两个 bool?
.
编辑:
看来 bool?
的原因是 Foo?.Any()
本身。如果你不想和true
比较,我建议你有临时变量:
bool? any = Foo?.Any();
if (any.Value) ...
或者,如果对象是 class,您可以使用 FirstOrDefault() != null
作为检查条件。它不会花时间,因为它只会得到第一个对象:
if (Foot?.FirstOrDefault() != null)...
虽然我会使用临时变量或 Foo?.Any() == true
选项。
原文:
注意:令我惊讶的是 if (a?.Any())
后面不能跟 .Value()
或 .Value
(!)。
我想你需要的是 Value
(属性) 没有 ()
(方法):
if (Foo?.Any()?.Value) ...
bool?
有 .Value
(属性) 这是 bool
.
Any()
returns bool
但是 Foo?.Any()
会 return bool?
因此 Foo?.Any().Value
不会编译,因为 Any()
return 是一个没有成员 Value
的 bool
。
如果Foo
是null
,Any()
将不会被执行,因为该语句将return null
不解释[=后面的部分23=]运算符。
但是如果你把 Foo?.Any()
放在括号中,你就可以使用类型 bool?
的结果并通过 Value
或 GetValueOrDefault()
检查它:
(Foo?.Any()).GetValueOrDefault()
更多语法糖,空合并运算符。 C# 8.0 或更高版本
if (Foo?.Any() ?? false) { }