如何避免多次if null检查

时间:2010-10-09 18:08:16

标签: c# null

  

可能重复:
  Deep Null checking, is there a better way?
  C# elegant way to check if a property's property is null

我必须在这样的深层对象模型中进行查找:

  p.OrganisationalUnit.Parent.Head.CurrentAllocation.Person;

无论如何都要评估它并且如果任何链为null(organizationalunit,parent,head等),则返回null,而不必执行

if (p.org == null && p.org.Parent == null && p.org.Parent.Head . . .     

5 个答案:

答案 0 :(得分:8)

您正在寻找某些语言(例如Groovy)具有的null-safe dereference运算符?.(也称为安全导航),但遗憾的是C#没有此运算符。

希望有一天能实施....

另见Eric Lippert的this post。他提出的语法是.?

答案 1 :(得分:7)

您听说过Law of Demeter吗?

链接如此长的呼叫序列并不是一个好主意。它会在您不需要的类之间创建可怕的依赖关系。

在您的示例中,包含p的类将依赖于五个其他类。我建议你简化你的代码,让每个类在他们自己的知识背景下检查单个级别的空值。

答案 2 :(得分:6)

结帐this article。它提供了一个很好的解决方案,可以让你写出这样的东西:

p.With(x => x.OrganisationalUnit)
 .With(x => x.Parent)
 .With(x => x.Head)
 .With(x => x.CurrentAllocation
 .With(x => x.Person);

答案 3 :(得分:0)

要回答标题中的问题,可以避免使用“demeter法则”并创建一个名为GetHeadOfParentOrganizationalUnit()的方法

我不确定该解决方案是否适用于您的特定情况,但如果您可以取消所有这些空检查,那么值得一看。

另请参阅:a link

答案 4 :(得分:-2)

您也可以使用基本的异常处理来捕获它。我并不为这个解决方案而疯狂,但这是一个选择。如果这些嵌套的空值是正常操作,则异常可能不是正确的答案:

public class A
{
}
public class B
{
   public A a;
}
public class C
{
    public B b;
}
class Program
{
    static A GetA(C c)
    {
        A myA;
        try
        {
            myA = c.b.a;
        }
        catch
        {
            myA = null;
        }
        return myA;
    }        

    static void Main(string[] args)
    {
        C theC = new C();
        theC.b = new B();
        theC.b.a = new A();
        A goodA = GetA(theC);
        if (goodA != null)
        {
            Console.WriteLine("Expected nominal path.");
        }
        else
        {
            Console.WriteLine("Unexpected nominal path.");
        }
        theC.b.a = null;
        A badA = GetA(theC);
        if (badA == null)
        {
            Console.WriteLine("Expected off-nominal path.");
        }
        else
        {
            Console.WriteLine("Unexpected off-nominal path.");
        }

    }

}