C# Nullcheck多级对象

C# Nullcheck多级对象,c#,C#,在继续之前,我一直在尝试一些简单的方法来检查多个嵌套对象,看看是否有空对象。如果可能的话,我尝试使用Null条件运算符将多个嵌套的if语句替换为单个语句 到目前为止,我有这样的想法: if ((Object1?.Object2?.Object3?.Object4 != null) ? true : false) { ... } 上述方法是否能有效识别Object1、2、3或4是否为null,如果为null,则返回false?我很想知道有没有更好的解决方案 TIA您不需要返回false或true

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

到目前为止,我有这样的想法:

if ((Object1?.Object2?.Object3?.Object4 != null) ? true : false)
{
...
}
上述方法是否能有效识别Object1、2、3或4是否为null,如果为null,则返回false?我很想知道有没有更好的解决方案


TIA

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

if (Object1?.Object2?.Object3?.Object4 != null)
如果嵌套对象中的任何一个为空,则此部分是检查嵌套对象的完全有效选项。您可以在文档中找到完全相同的示例:

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

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


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

if (Object1?.Object2?.Object3?.Object4 != null)
如果嵌套对象中的任何一个为空,则此部分是检查嵌套对象的完全有效选项。您可以在文档中找到完全相同的示例:

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

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

代码

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>);
}
public void Foo()
{
如果((NullCheck(Object1)!=null)?真:假)
{
...
}
}
私有可为NullCheck(Object1Type object1)
{
如果(!Object.referenceequals(object1,null))//这是“object1”
{
var tmpObject2=tmpObject1.Object2;
如果(!Object.referenceequals(tmpObject2,null))//这是“Object2”
{
var tmpObject3=tmpObject2.Object3;
如果(!Object.referenceequals(tmpObject3,null))//这是“Object3”
{
返回tmpObject3.Object4;
}        
}
}
返回默认值(可为空);
}
因此,只有在所有对象都不为null的情况下,
才会运行,如果较低级别的对象为null,则以后的对象永远不会得到计算。

代码

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>);
}
public void Foo()
{
如果((NullCheck(Object1)!=null)?真:假)
{
...
}
}
私有可为NullCheck(Object1Type object1)
{
如果(!Object.referenceequals(object1,null))//这是“object1”
{
var tmpObject2=tmpObject1.Object2;
如果(!Object.referenceequals(tmpObject2,null))//这是“Object2”
{
var tmpObject3=tmpObject2.Object3;
如果(!Object.referenceequals(tmpObject3,null))//这是“Object3”
{
返回tmpObject3.Object4;
}        
}
}
返回默认值(可为空);
}

因此,只有当所有对象都不为null时,
才会运行,而如果较低级别的对象为null,则以后的对象将永远不会得到计算。

您目前拥有的是完全按照您的要求执行操作的最佳方法。我想回答这个问题是为了说明如果您无法访问最新的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)
    {
        ...
    }

你现在拥有的是做你想做的事情的最好方式。我想回答这个问题是为了说明如果您无法访问最新的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)
    {
        ...
    }

那个?true:false’不需要以这种方式使用语法是可以的,但是一个需要您对这么多级别执行此操作的设计是有问题的?true:false’不需要以这种方式使用语法是可以的,但要求您对这么多级别执行此操作的设计是有问题的。因此,只有当所有对象都不是null时,此值才会计算为true?如果说Object2为null,则不会抛出和异常?@Nugs yes,exactly@Nugs更正这是
运算符的整个点。
运算符。它只计算它找到的第一个空值,然后返回一个
default(Object4Type)
(或者如果
Object4Type
是一个结构,则返回一个
default(Nullable)
)与
!=null
。太棒了,我想我的思路是正确的,但我想确认一下,并更好地理解如何最好地使用null条件运算符。我很感激这一课和大家的确认!Thx一定要为此感谢C#团队。空安全点操作符是C#6语言规范中最近添加的一个操作符,与.NET 4.5和Visual Studio 2015一起发布。在此之前,最好的解决方案是一个扩展方法,它看起来像
Object1.OrDefault(o=>o.Object2.Object3.Object4)
,基本上包装了一个try-catch块,试图计算lambda,捕获任何
NullReferenceException
s或
invalidooperationexception
s,并在这些情况下返回null。空安全点更干净。所以只有当所有对象都不为空时,才会计算为真?如果说Object2为null,则不会抛出和异常?@Nugs yes,exactly@Nugs更正这是
运算符的整个点。
运算符。它只计算它找到的第一个空值,然后返回一个
default(Object4Type)
(或者如果
Object4Type
是一个结构,则返回一个
default(Nullable)
)与
!=null
。太棒了,我想我的思路是正确的,但我想确认一下,并更好地理解如何最好地使用null条件运算符。我很感激这一课和大家的确认!Thx并且一定要感谢C#