2017-07-18 28 views
5

我试图安全地检查IList<>是否为空。如何为布尔条件的空合并?

var Foo = Bar.GimmeIListT(); // Returns an IList<SomeObject> 
if (Foo?.Any()) 
    // Do cool stuff with items in Foo 

但没有与条件的错误:“布尔”

无法隐式转换到'布尔'。一个显式转换存在(是否缺少强制转换?)

如此看来条件的计算结果为可空布尔,所以我尽量

if (Foo?.Any().Value()) 

但是,这是没有好或者:

“布尔”不包含“值”的定义,并没有扩展....等等等等

所以在F等等第一个例子它抱怨说它是一个可空的布尔,但在第二个它抱怨它不是。

作为另一种途径我尝试:

if (Foo?.Any() == true) 

此工程 - 但它不应该,因为这里采用隐式转换,其第一条消息说,它不想!

这是怎么回事?什么是正确的方法来做到这一点?

+0

如果(?富.Count之间> 0){} –

+1

@ AndzejMaciusovic:这是一个糟糕的方式。如果'Foo'实际上是一个需要数小时才能完成的查询,那么你会错过任何'糟糕的'。如果你想知道是否至少有一个,不要全数。 –

+1

@TimSchmelter在我的示例中,我使用.Count而不是Count().Count已经是IList计算的字段,实际上使用.Count代替.Any()会快一点。在列表上。 –

回答

7

如果使用==你可以用bool?比较,这的确是最好/最简单的方法:

if (Foo?.Any() == true) ... 

至于为何没有在if==允许,Jon Skeet can explain它好得多:

没有从Nullable到bool的隐式转换。 是一个从bool到Nullable的隐式转换,这就是 对第一个 版本中的每个bool常量发生的事情(用语言表达)。的布尔运算符==(可为空的,可为空的操作者 然后施加(这不是完全一样的其它运营商解除 - 。结果却BOOL,不可为空)

换句话说,表述“弗雷德==假”是bool类型的, 而表达‘弗雷德’的类型为可空,因此你可以 不使用它作为‘如果’的表达。

所以if只允许bool但你具有bool?,但==运营商将bool转换为bool? d你可以比较两个bool?

+2

OP已经尝试过_This工程 - 但它不应该,因为它使用了第一个消息说它不想要的隐式转换!_ – Pikoh

+1

@Pikoh:fixed :) –

+1

使用@JonSkeet卡吗? :)对,现在它解释了它,+1 – Pikoh

3

编辑

这似乎是bool?的原因是Foo?.Any()本身。如果你不想把它与true比较,我建议你有临时变量:

bool? any = Foo?.Any(); 
if (any.Value) ... 

或者,如果对象是类,你可以使用FirstOrDefault() != null作为检查的条件。它不会需要时间,因为它只会得到的第一个对象:

if (Foot?.FirstOrDefault() != null)... 

我将与临时变量或虽然Foo?.Any() == true选项去。

原始

注:这是出乎我的意料太那个if (a?.Any())不能跟着.Value().Value(!)。

我想你需要的是Value(属性)无()(方法):

if (Foo?.Any()?.Value) ... 

bool?.Value(财产)这是一个bool

1

Any()回报boolFoo?.Any()将返回bool?

所以Foo?.Any().Value不会编译,因为Any()返回bool不具有成员Value

如果FoonullAny()将不被执行,因为该语句将返回null不解释?.操作者身后有一部分。

但是,如果你把Foo?.Any()在paranthesis,您可以用bool?类型的结果工作,并通过ValueGetValueOrDefault()检查:

(Foo?.Any()).GetValueOrDefault()