2009-04-17 10 views
4

オブジェクト階層内のヌル参照を処理するうまい方法を探しています。オブジェクト階層内のヌル参照を処理するためのより良い方法

すなわち:Object2にはnullであると言う場合

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

この例では、null参照の例外がスローされます。

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

私は実験しましたか?これは2つのレベルの後にいくつかの醜い探しているコードのためになります。

感謝しています。

答えて

6

これは正接である可能性があります...しかし、私は醜さと痛みを避けるためにデザインの変更をお勧めします

law of demeterに違反しています。代わりに、そのプロパティに到達するはずであれば、Object1はProperty自体を公開する必要があります... Object1.RetrievedFromTheDepthsProperty
これはなぜ必要なのですか?Type2のデザイナーが返されるObjectの型を変更した場合'Object3'フィールド/プロパティによって、あなたが探しているプロパティを持たないものには、あなたはホースされます。クライアントは、Object1の内部構造についてあまり知っていません。データが内部的にどこに配置されているかをObject1でカプセル化すると、将来の変更に対して安全です。必要に応じて、また、このプロパティは内部的にチェックすべてのNULLを行うことができます...非常にクリーン

if (Object1.RetrievedFromTheDepthsProperty == null) {...} 
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回呼び出すことは望ましくありません。(プロパティよりも多くの作業が必要です)

0

一般に、あなたがどのプロパティがnullであっても問題がなければオブジェクト階層のみそれに対してテストしないでください。アプリケーション用のグローバルエラーハンドラを使用します(これはアプリケーションASP.NET、WinFormsなどのタイプに依存します)、何か問題があったとします。

1

は直接あなたの質問に答えていない - ちょうどいくつかのヒント:

  • はそれだけで多分いくつかの方法で、これまでのところ(あなたの三つのレベル)の階層を通過するために、適切ないないようだNull object
  • を使用してみてください条件に答える最初の/ 2番目のレベルは、助けになるでしょう
2

Null Object patternを使用できます。

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); 

注意をあなたの全体モデルの "ヌルオブジェクト" を定義する作業のかなり多くあること。また、モデルのユーザーを混乱させないように細心の注意を払う必要があります。ヌルを渡してチェックするのを忘れた場合、コードはすぐに爆発する傾向がありますが、実際のオブジェクトではないため、コールスタックの深部まで生き延びやすく、微妙な問題を引き起こす可能性があります。

+0

実際には、これを使う正しい場所(あなたのやり方について考える)に気を付ける必要がありますが、このパターン - 私が知る限り、センチネルパターンとも呼ばれますか?実際の命を救うことができます。私はそれが好きで、体重を加えるたびにそれを使用して話す。 – peSHIr

関連する問題