C# Nullcheck多级对象
在继续之前,我一直在尝试一些简单的方法来检查多个嵌套对象,看看是否有空对象。如果可能的话,我尝试使用Null条件运算符将多个嵌套的if语句替换为单个语句 到目前为止,我有这样的想法:C# Nullcheck多级对象,c#,C#,在继续之前,我一直在尝试一些简单的方法来检查多个嵌套对象,看看是否有空对象。如果可能的话,我尝试使用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) ? 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#