4

オブジェクト階層で null 参照を処理する良い方法を探しています。

すなわち:

if(null == Object1.Object2.Object3.Property)

この例では、Object2 が null であると言うと、Null 参照例外がスローされます。

私の場合、何がnullかは気にしません。何かがそうであることだけです。このようなことをしたい場所ごとに try/catch を配置したくないので、代わりの方法を探していました。

私は??で実験しました。演算子ですが、これは 2 つのレベルの後で見苦しいコードになります。

どんなアイデアでも大歓迎です。

4

6 に答える 6

6

今、これは正接しているかもしれません...しかし、醜さと痛みを避けるためにデザインを変更することをお勧めします

呼び出しはデメテルの法則にObject1.Object2.Object3.Property違反します。代わりに、そのプロパティにアクセスすることになっている場合、Object1はプロパティ自体を公開する必要があります...したがって、 なぜこれが必要なのかを呼び出す必要があります。タイプObject2の設計者が、によって返されるオブジェクトのタイプを変更した場合、 Object3のフィールド/プロパティを、探しているプロパティがないものに変更すると、問題が発生します。クライアントは、Object1の内部構造についてよく知っています。Object1がデータが内部的に配置されている場所にカプセル化されている場合、将来の変更に対して安全です。また、このプロパティは、必要に応じて内部ですべてのnullチェックを実行できます...はるかにクリーンな状態になりますObject1.RetrievedFromTheDepthsProperty

if (Object1.RetrievedFromTheDepthsProperty == null) {...}
于 2009-04-17T08:10:35.663 に答える
2

NullObjectパターンを使用できます。

class Car {
    Engine engine = null;

    public Engine Engine { 
        get { 
            return engine ?? new NullEngine();
        }
    }
}

class Engine {
    string make;
    public virtual string Make { get { return make; } }
}

class NullEngine : Engine {
    public override string Make { get { return null; } }
}

次に、次のことができます。

Car car;
if (car.Engine.Make != null) Console.WriteLine(car.Engine.Make);

それ以外の:

Car car;
if (car.Engine != null && car.Engine.Make != null) Console.WriteLine(car.Engine.Make);   

モデル全体に​​「nullオブジェクト」を定義するのは非常に手間がかかることに注意してください。また、モデルのユーザーを混乱させないように細心の注意を払う必要があります。nullを渡してチェックするのを忘れると、コードはすぐに爆発する傾向がありますが、「nullオブジェクト」は実際のオブジェクトではないため、コールスタックの奥深くまで存続しやすく、微妙な問題を引き起こす可能性があります。

于 2009-04-17T08:05:10.077 に答える
2

これ (null セーフな逆参照) は、時折発生するものです。現時点では、以下を除いてきちんとした答えはありません。

if(Object1 == null || Object1.Object2 == null
        || Object1.Object2.Object3 == null
        || Object1.Object2.Object3.Property == null)

必要に応じて (変数を導入することで) いくつかの小さなキャッシュを実行できますが、それはさらに醜くなります。

SomeType2 obj2;
SomeType3 obj3;
if(Object1 == null || (obj2 = Object1.Object2) == null
        || (obj3 = obj2.Object3) == null
        || obj3.Property == null)

一般に、プロパティを 2 回呼び出したくない場合を除き、上記の方法はお勧めしません (プロパティよりも多くの作業を行うため)。

于 2009-04-17T07:43:19.193 に答える
1

あなたの質問に直接答えるのではなく、いくつかのヒント:

  • Null オブジェクトを使用してみてください
  • ここまでの階層 (3 つのレベル) を通過するのは適切ではないようです。条件に答える第 1/第 2 レベルのメソッドが役立つかもしれません。
于 2009-04-17T08:04:43.197 に答える
0

一般に、オブジェクト階層でどのプロパティが null であるかを気にしない場合は、それに対してテストしないでください。アプリケーションのグローバル エラー ハンドラーを使用し (これは、ASP.NET、WinForms などのアプリケーションの種類によって異なります)、ユーザーに問題が発生したことを伝えます。

于 2009-04-17T07:49:46.370 に答える
0

次の投稿を確認することを強くお勧めします: http://www.hardcodet.net/2008/12/observe-dependencies-through-lambda-expressions-part1

これは同様の問題を指しており、変更を簡単に処理することもできます。

于 2009-05-18T11:15:27.887 に答える