Nullcheck多级对象

时间:2017-04-11 20:25:49

标签: c#

我一直在玩一些更简单的方法来检查多个嵌套对象,看看在继续之前是否有null。我正在尝试使用Null条件运算符将多个嵌套的if语句替换为单个语句。

到目前为止,我有这样的事情:

if ((Object1?.Object2?.Object3?.Object4 != null) ? true : false)
{
...
}

以上是否有效识别Object1 2 3或4是否为空,如果是,则返回false?我很想知道是否有人有更好的解决方案?

TIA

3 个答案:

答案 0 :(得分:6)

您不需要返回false或true - 布尔条件本身具有布尔值:

if (Object1?.Object2?.Object3?.Object4 != null)

如果嵌套对象中的任何一个为null,则此部分是一个完全有效的选项。您可以在null-conditional operator文档中找到完全相同的示例:

// null if customers, the first customer, or Orders is null  
int? count = customers?[0]?.Orders?.Count();

并解释:

  

最后一个示例演示了null条件运算符   短路。如果一个条件成员链中的一个操作   访问和索引操作返回null,然后是链的其余部分   执行停止。

答案 1 :(得分:0)

代码

public void Foo()
{
    if ((Object1?.Object2?.Object3?.Object4 != null) ? true : false)
    {
    ...
    }
}

在逻辑上等同于

public void Foo()
{
    if ((NullCheck(Object1) != null) ? true : false)
    {
    ...
    }
}

private Object4Type NullCheck(Object1Type object1)
{
    if(!Object.RefrenceEquals(object1, null)) //This is "Object1?."
    {
        var tmpObject2 = tmpObject1.Object2;
        if(!Object.RefrenceEquals(tmpObject2, null)) //This is "Object2?."
        {
            var tmpObject3 = tmpObject2.Object3;
            if(!Object.RefrenceEquals(tmpObject3, null)) //This is "Object3?."
            {
                return tmpObject3.Object4;
            }        
        }
    }
    return default(Object4Type);
}

或者Object4Type是结构

public void Foo()
{
    if ((NullCheck(Object1) != null) ? true : false)
    {
    ...
    }
}

private Nullable<Object4Type> NullCheck(Object1Type object1)
{
    if(!Object.RefrenceEquals(object1, null)) //This is "Object1?."
    {
        var tmpObject2 = tmpObject1.Object2;
        if(!Object.RefrenceEquals(tmpObject2, null)) //This is "Object2?."
        {
            var tmpObject3 = tmpObject2.Object3;
            if(!Object.RefrenceEquals(tmpObject3, null)) //This is "Object3?."
            {
                return tmpObject3.Object4;
            }        
        }
    }
    return default(Nullable<Object4Type>);
}

因此,只有当所有对象都不为null且低级对象为null时,才会运行...,后来的对象永远不会被评估。

答案 2 :(得分:0)

您所拥有的是目前正是您想要的最佳方式。我想回答一下,如果您无法访问最新的C#6语言功能,那么就说明了什么是必要的。这是在.NET 3.5-4.0中进行相同检查的下一个最易于开发人员的方式:

    //boilerplate, off in your extension method library
    public static TOut OrDefault<TIn, TOut>(this TIn input, 
        Func<TIn, TOut> possiblyNullFunc)
    {
        try { return possiblyNullFunc(input); }
        catch (NullReferenceException) //for most reference types
        { return default(TOut); }
        catch (InvalidOperationException) //for Nullable<T>
        { return default(TOut); }
    }

    ...

    //usage
    if (Object1.OrDefault(o=>o.Object2.Object3.Object4) != null)
    {
        ...
    }

它的功能非常好,直到您尝试在自己的类中使用InvalidOperationException来处理除null成员访问以外的情况。

仍然打破这个裤子,特别是如果你必须经常做这个检查:

if(Object1 != null
    && Object1.Object2 != null
    && Object1.Object2.Object3 != null
    && Object1.Object2.Object3.Object4 != null)
{
    ...
}