2017-07-18 8 views
5

IList<>が空でないかどうかを安全に確認しようとしています。ブール条件の合併をヌルにする方法は?

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

しかし、条件付きエラーがある:

は、暗黙のうちに 'ブール?' に変換できませんブールに

:明示的な変換は、だから、条件がNULL可能ブール値に評価され、私は

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

を試すようだが、これはどちらか良くない(?あなたはキャストが欠落している)

が存在します

「ブール」....「価値」と拡張子なしの定義が含まれていません何とか何とか何とか

だから、Fで最初のインスタンスでは、それがnullのboolであると文句を言いますが、2番目のインスタンスでは、それはそうではないと文句を言います。

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

これは動作します - それは、これは最初のメッセージは、それが望んでいないと言った暗黙の型変換を使用するべきではありませんので:別の道として

は、私が試してみてください!

何が起こっていますか?これを行う正しい方法は何ですか?

+0

場合(?Fooの.Count> 0){} –

+1

@ AndzejMaciusovic:それは悪い方法です。 'Foo'が実際に完全に実行するのに何時間もかかるクエリであれば、' Any'が間違って見逃されるでしょう。少なくとも1つがあるかどうかを知りたい場合は、すべてを数えないでください。 –

+1

@TimSchmelter私の例では、Countを使用していません.Count().Countは既にIListの計算フィールドです。実際は.Any()の代わりに.Countを使用する方が少し速いです。リスト上。 –

答えて

7

あなたは==を使用している場合、それは確かに最高/最も簡単な方法ですbool?と比較することができます:それはifではなく==で許可されていない理由として

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

Jon Skeet can explainそれははるかに良い:

Nullableからboolへの暗黙的な変換はありません。 は、boolからNullableへの暗黙的な変換であり、 のバージョンの各ブール定数に対して が(言葉で言えば)何か起こります。ブール演算子==は、(NULL可能で、NULL可能オペレータ 次いで適用される(これは他の持ち上げオペレータ と全く同じではありません - 。結果は、ブール値だけNULL可能ではない)

言い換えれば、式 'フレッド型であるのNullableは、したがって、あなたが のでifができます表現 『場合』。

だけboolが、あなたとしてそれを使用することはできませんフレッド== falseが」式は、一方で、bool型の は ' bool?がありますが、==演算子はboolbool?に変換します。あなたは2つを比較することができますbool?

+2

OPは既にこれを試しました_これはうまくいきますが、最初のメッセージが望ましくないと言った暗黙的な変換を使用しているからではないでしょうか_ – Pikoh

+1

@Pikoh:fixed :) –

+1

@JonSkeetカードを使用していますか? :)右、今それはそれを説明します、+1 – Pikoh

3

編集

bool?の原因はFoo?.Any()そのものであるように思えます。あなたはtrueと比較したくない場合は、私は一時的な変数を持っているあなたをお勧めします:

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

、オブジェクトがクラスである場合は、条件をチェックするようFirstOrDefault() != null使用することができます。私も一時変数またはFoo?.Any() == trueオプションと一緒に行きます

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

:それだけで最初のオブジェクトを取得しますので、それは時間がかかることはありません。

オリジナル

注:それはif (a?.Any()).Value()または.Valueを続けることができないことにも驚いたことにあります(!)。私は何が必要だと思う

()(メソッド)なしValue(プロパティ)です:

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

bool?boolある.Value(プロパティ)を持っています。

1

Any()戻りboolしかしFoo?.Any()Any()がメンバーValueを持っていないboolを返しますので、そうFoo?.Any().Valueがコンパイルされませんbool?

を返します。

Foonullであれば文は?.オペレータの後ろの部分を解釈せずnullを返しますので、Any()は実行されません。

しかし、あなたがparanthesisでFoo?.Any()を置けば、あなたがタイプbool?の結果と協力し、ValueまたはGetValueOrDefault()を経由して、それをチェックすることができます:

(Foo?.Any()).GetValueOrDefault() 
関連する問題