2009-04-17 33 views
4

我正在寻找一种很好的方法来处理对象层级中的空引用。处理对象层级中的空引用的更好方法

即:

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

这个例子,如果说是Object2的空将抛出一个空引用异常。

在我的情况下,我不在乎什么是空,只是有些事情。 我并不是真的想在每个我想要做这样的事情的地方都尝试/捕捉,所以我一直在寻找替代品。

我已经试验过?但是这会在两个级别之后产生一些丑陋的代码。

任何想法赞赏。

回答

6

现在这可能是一个切线...但我会建议一个设计更改,以避免丑陋和疼痛

调用Object1.Object2.Object3.Property违反law of demeter。相反,如果你应该去那个属性,Object1应该公开一个属性本身...所以你应该叫Object1.RetrievedFromTheDepthsProperty
为什么这是必要的..是,如果类型Object2的设计器更改返回的对象的类型通过'Object3'字段/属性找到一个没有你正在寻找的属性的对象,你会被洗掉。客户对Object1的内部结构知之甚多。如果将Object1封装在数据位于内部的位置,则可以避免将来的更改。另外这个属性可以做所有的空按照要求在内部检查......让你用更清洁

if (Object1.RetrievedFromTheDepthsProperty == null) {...} 
2

这个(无效的解除引用)是偶尔会引发的事情,而不是;没有令人满意的答案,此刻,除了:

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) 

在一般情况下,我会建议对上述情况,除非你真的,真的不想两次致电属性(因为它做的比物业应该更多的工作)

0

一般来说,如果你不在乎你的哪个属性为null对象层次结构不要对它进行测试。为应用程序使用全局错误处理程序(这取决于应用程序ASP.NET,WinForms,...的类型),并说用户出了问题。

1

不能直接回答你的问题 - 只是一些提示:

  • 尝试使用Null object
  • 它只是似乎并不适合在层次结构这一步(您三级)去的,也许一些方法将回答条件的第一个/第二个级别将帮助
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); 

请注意,这是一个相当大量的工作来界定 “空对象” 为您的整个模型。您还需要非常小心,以免混淆模型的用户。如果你传递null并忘记检查它,代码往往会很快炸毁,但是一个“空对象”可以更容易地深入到调用堆栈中,并且由于它不是一个真正的对象,所以会导致一些细微的问题。

+0

你确实需要注意正确的地方来使用它(想想你在做什么),但是据我所知,这种模式 - 也被称为哨兵模式? - 可以成为真正的生活救星。我喜欢它,只要它增加它的重量就可以使用它,可以这么说。 – peSHIr 2009-04-17 08:12:23

相关问题