4

我正在寻找一种处理对象层次结构中空引用的好方法。

IE:

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

如果说 Object2 为空,此示例将引发空引用异常。

就我而言,我不在乎什么是空的,只是有些东西是空的。我真的不想在我想做这样的事情的每个地方都放置 try/catch,所以我一直在寻找替代方案。

我实验过??运算符,但这会在两个级别之后产生一些难看的代码。

任何想法表示赞赏。

4

6 回答 6

6

现在这可能是切线......但我建议改变设计以避免丑陋和痛苦

呼叫Object1.Object2.Object3.Property违反了得墨忒耳法则。相反,如果您应该获得该属性,则 Object1 应该公开一个属性本身...所以您应该调用Object1.RetrievedFromTheDepthsProperty
为什么需要这样做.. 如果 Type Object2 的设计者更改了由 ' 返回的 Object 的类型Object3' 字段/属性到没有您要查找的属性的字段/属性,您将被冲洗掉。客户端对Object1的内部结构了解太多。如果 Object1 封装了内部数据所在的位置,那么您可以安全地应对未来的更改。此外,此属性可以根据需要在内部进行所有空值检查......让您更清洁

if (Object1.RetrievedFromTheDepthsProperty == null) {...}
于 2009-04-17T08:10:35.663 回答
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)

一般来说,我建议不要使用上述方法,除非你真的、真的不想调用一个属性两次(因为它比属性应该做的工作更多)

于 2009-04-17T07:43:19.193 回答
2

您可以使用Null Object 模式

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 对象”可以更容易地深入调用堆栈并导致微妙的问题,因为它不是一个真实的对象。

于 2009-04-17T08:05:10.077 回答
1

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

  • 尝试使用Null 对象
  • 到目前为止,似乎不适合通过层次结构(您的三个级别),也许在第一/第二级别上可以回答条件的某种方法会有所帮助
于 2009-04-17T08:04:43.197 回答
0

通常,如果您不关心对象层次结构中哪个属性为空,则不要对其进行测试。为应用程序使用全局错误处理程序(这将取决于应用程序 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 回答