Null伝播演算子/条件付きアクセス式 が c#-6. に登場すると、非常に便利な機能のように見えます。しかし、子メンバーがnullでないかどうかを確認し、ifブロック内でその子メンバーに対してブールメソッドを呼び出す問題の解決に役立つかどうか、私は興味があります。
_ public class Container<int>{
IEnumerable<int> Objects {get;set;}
}
public Container BuildContainer()
{
var c = new Container();
if (/* Some Random Condition */)
c.Objects = new List<int>{1,2,4};
}
public void Test()
{
var c = BuildContainer();
//Old way
if ( null != c && null != c.Objects && c.Objects.Any())
Console.Write("Container has items!");
//C# 6 way?
if (c?.Object?.Any())
Console.Write("Container has items!");
}
_
c?.Object?.Any()
はコンパイルされますか?伝搬演算子がnullに短絡した場合(私はそれが正しいと思います)、if (null)
があり、これは無効です。
C#チームはこの問題に対処しますか、それともnull伝播演算子の意図した使用例を見逃していますか?
この方法では機能しません。説明をスキップして、以下のコードを参照してください:)
ご存じのとおり、子メンバーがnullの場合、_?.
_演算子はnullを返します。しかし、Any()
メソッドのように、bool
を返すnull不可のメンバーを取得しようとするとどうなりますか?答えは、コンパイラが戻り値を_Nullable<>
_に「ラップ」することです。たとえば、Object?.Any()
は、bool
ではなく_bool?
_(_Nullable<bool>
_)を提供します。
この式をif
ステートメントで使用できないのは、暗黙的にbool
にキャストできないことです。しかし、あなたは明示的に比較を行うことができます、私はこのようにtrue
と比較することを好みます:
_if (c?.Object?.Any() == true)
Console.Write("Container has items!");
_
@ DaveSextonに感謝 別の方法があります:
_if (c?.Object?.Any() ?? false)
Console.Write("Container has items!");
_
しかし、私にとっては、true
との比較はより自然に見えます:)
NULL条件演算子は、null
または式の最後の値を返します。 value types の場合、結果はNullable<T>
で返されるため、あなたの場合はNullabe<bool>
になります。 C#の今後の機能(指定された ここ )のドキュメントの例を見てみると、例があります:
int? first = customers?[0].Orders.Count();
上記の例では、int
の代わりにNullable<int>
が返されます。 bool
の場合、Nullable<bool>
を返します。
Visual Studio "14" CTP で次のコードを試した場合:
Nullable<bool> ifExist = c?.Objects?.Any();
上記の行の結果はNullable<bool>
/bool?
になります。後で、次のように比較できます。
null-coalescing operator ?? を使用する
if (c?.Object?.Any() ?? false)
Nullable<T>.GetValueOrDefault
メソッドの使用
if ((c?.Objects?.Any()).GetValueOrDefault())
true
との比較を使用する
if (c?.Objects?.Any() == true)