2

そのため、グーグルでもスタックオーバーフローでも、これに対するエレガントな解決策は見つかりませんでした。私は非常に特定の状況を手にしていると思いますが、とにかくここに行きます:

外部 WS からこの構造を受け取るため、制御できないオブジェクト構造があります。これは非常に巨大なオブジェクトで、さまざまなレベルのフィールドとプロパティがあり、このフィールドとプロパティはどのレベルでも null にすることも、null にすることもできません。このオブジェクトは貧血モデルと考えることができます。これには動作がなく、状態だけがあります。

この質問のために、私の状況をシミュレートする簡単なサンプルを提供します。

Class A
  PropB1
    PropC11
      PropLeaf111
    PropC12
      PropLeaf112
  PropB2
    PropC21
      PropLeaf211
    PropC22
      PropLeaf221

そのため、コード全体で、必要なものを計算するためにいくつかの計算を行うために、さまざまなレベルでこれらの多くのプロパティにアクセスする必要があります。基本的に、実行する必要がある計算の種類ごとに、必要なプロパティの各レベルをテストして、null でないかどうかを確認する必要があります。null でない場合は、(10 進数) 0 を返すか、状況に応じて他の既定値を返します。ビジネスロジック。

私がそれをしなければならない数学のサンプル:

var value = 0;
if (objClassA.PropB1 != null && objClassA.PropB1.PropC11 != null) {
  var leaf = objClassA.PropB1.PropC11.PropLeaf111;
  value = leaf.HasValue ? leaf.Value : value;
}

念のために言うと、この構造体のリーフ プロパティは常にプリミティブ、または null 許容プリミティブであり、その場合は適切に処理します。これは、必要な各プロパティに対して実行する必要がある「ロジック」であり、場合によってはそれらのかなりの数を使用する必要があります。また、実際の構造は非常に大きいため、必要なプロパティごとに必要な検証の数も多くなります。

さて、私はいくつかのアイデアを思いつきましたが、どれも理想的ではないと思います。

  1. プロパティを収集するメソッドを作成して、必要な検証を抽象化するか、デフォルト値を取得するロジックを作成します。欠点は、いくつかのフィールドのグループで検証とデフォルト値が似ているため、私の意見では、コードがかなり重複していることです。
  2. オブジェクトを受け取る単一のジェネリック メソッドと、必要なフィールドにアクセスするラムバ関数を作成します。このメソッドは、関数を実行してその結果を返そうとします。NullReferenceException の場合は、デフォルト値を返します。これの明るい面は、それが本当に汎用的であることです。プロパティにアクセスするためにラムダを渡すだけで、メソッドは問題を処理します。その欠点は、私が try -> catch を使用してロジックを制御していることです。これは目的ではありません。コードは、最終的にメンテナンスを行う他のプログラマにとって混乱を招く可能性があります。
  3. Null Object パターン、これが最もエレガントなソリューションだと思います。通常のケースであれば、すべての良い点があります。しかし問題は、この構造に Null オブジェクトを提供することの影響です。もう少し文脈を説明すると、私が取り組んでいるソフトウェアは政府のサービスと統合されており、政府の仕様にある私が取り組んでいる構造には、null が何らかの意味を持つフィールドがいくつかあります。 「0」のようなデフォルト値。また、この仕様は時々変更され、クラスが再生成され、Null オブジェクトを作成するために必要な後処理もメンテナンスが必要になり、少し危険に思えます。

私は自分自身を十分に明確にしたことを願っています。

前もって感謝します。

解決

これは、受け入れられた回答に基づいて、問題をどのように解決したかについての回答です。

私は C# にまったく慣れていません。リンクされたこの種の議論は、多くの面でエレガントなソリューションを思いつくのに本当に役立ちました。コードが実行される場所によっては.NET 2.0を使用するという問題がまだありますが、拡張メソッドをある程度定義できるこの問題の解決策も見つけました: https://stackoverflow.com/a/707160/649790

そして、ソリューション自体については、これが最高であることがわかりました: http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad

基本的に、この方法でプロパティにアクセスし、計算を行うだけです。

objClassA.With(o => o.PropB1).With(o => PropC11).Return(o => PropLeaf111, 0);

必要なプロパティごとに。それはまだただではありません:

objClassA.PropB1.PropC11.PropLeaf111

もちろん、これまでに見つけた解決策よりもはるかに優れています。私は拡張メソッドに慣れていなかったので、本当に多くのことを学びました.

再度、感謝します。

4

1 に答える 1