C#では、複数のレベルのヌル参照をチェックするクリーンな方法がありますか
-
02-10-2019 - |
質問
たとえば、以下に電話したい場合は、person.Head.Nose.Sniff()
次に、安全になりたい場合は、次のことをしなければなりません。
if(person != null)
if(person.Head != null)
if(person.Head.Nose != null)
person.Head.Nose.Sniff();
この式を策定する簡単な方法はありますか?
解決
この式を策定する簡単な方法はありますか?
C#6を使用すると、を使用できます ヌル条件演算子 ?
.
コードの例
これは、メソッドに詰め込まれた元のコードです Sniff()
常に戻ります true
:
public bool PerformNullCheckVersion1(Person person)
{
if (person != null)
if (person.Head != null)
if (person.Head.Nose != null)
return person.Head.Nose.Sniff();
return false;
}
これは、C#6 null-conditionalオペレーターで書き換えられたコードです。
public bool PerformNullCheckVersion2(Person person)
{
return person?.Head?.Nose?.Sniff() ?? false;
}
??
それは ヌルコーテンシングオペレーター そして、あなたの質問とは関係ありません。
完全な例については、以下を参照してください。https://github.com/lernkurve/stackoverflow-question-3701563
他のヒント
最初に、ブールロジック演算子の短絡を利用して、次のようなことを行うことができます。
if (person != null && person.Head != null && person.Head.Nose != null)
{
person.Head.Nose.Sniff();
}
また、あなたがしていることは、として知られているソフトウェアを開発するための設計ガイドラインに反することに注意してください デメテルの法則.
以下は、また、また、流fluentパラメーター検証の行に沿った別の実装です。 チェーンズされたヌルチェックと多分モナド
それ以外ではありません
if (person != null && person.Head != null && person.Head.Nose != null)
使用できます nullオブジェクト null値の代わりに。 Sniff
コールチェーン内のオブジェクトがnullオブジェクトである場合、何もしません。
これは例外を投げかけません:
person.Head.Nose.Sniff();
ヌルクラスは次のようになる可能性があります(シングルトンとして使用して、インターフェイスを使用することもできます。 IPerson
, IHead
と INose
):
class NullPerson : Person {
public override Head Head { get { return new NullHead(); }
}
class NullHead : Head {
public override Nose Nose { get { return new NullNose(); }
}
class NullNose : Nose {
public override void Sniff() { /* no-op */ }
}
サイドノートとして、酸素には オペレーター このため:
person:Head:Nose:Sniff;
使用できます 流fluentパラメーター検証
最良の方法は、それを使用することです &&
ネストの代わりにオペレーター if
ステートメント:
if (person != null && person.Head != null && person.Head.Nose != null)
{
person.Head.Nose.Sniff();
}
技術的には注意してください たぶん......だろう 同様のヌルチェックを実行します 式ツリーを使用します. 。あなたの方法には次のような署名があります:
static bool IsNotNull<T>(Expression<Func<T>> expression);
...これにより、このようなものを見てコードを書くことができます:
if (IsNotNull(() => person.Head.Nose))
{
person.Head.Nose.Sniff();
}
しかし、これには反省が含まれ、一般的に、あらゆる種類の詳細な方法で従うことははるかに困難です。 &&
方法。
の使用を取り除くでしょう null
そして、このようなことをします:
((Nose)person.BodyParts[BodyPart.Nose]).Sniff();
これには、ある種のベースが必要です class
また interface
.
public abstract class BodyPart
{
public bool IsDecapitated { get; private set; }
public BodyPart(bool isDecapitated)
{
IsDecapitated = isDecapitated;
}
}