是否可以使用 C# 安全导航运算符 (?.) 检查 Object 是否为空以及 属性?
Can a C# Safe Navigation Operator (?.) be used to check if Object is null, as well as property?
这主要是一道句法sugar/best-practice题。
这是一个有问题的代码示例:
if (_instanceData?.DataSourceType != null && Util.IsEntityBacked(_instanceData.DataSourceType) {// code}
我知道如果 _instanceData 为空,安全导航运算符将继续执行,但在这种情况下,条件中的第一个布尔值是否会按预期进行评估?这是否会成功地对 _instanceData 和 DataSourceType 进行空检查?
另一个例子:
if (LockAcquired && _instanceData?.ObjInfo != null) {// code}
在这种情况下,有可能_instanceData为null,也有可能不是,但ObjInfo为null。仅对对象和 属性 进行老式空检查是更好的做法,还是会按预期完成工作?
编辑:问题最好描述为:
if (obj?.prop != null)
是否等同于
if (obj != null && obj.prop != null)
第一个相当于
if (_instanceData != null && _instanceData.DataSourceType != null && Util.IsEntityBacked(_instanceData.DataSourceType) {// code}
第二个相当于
if (LockAcquired && _instanceData != null && _instanceData.ObjInfo != null) {// code}
所以它会检查 _instanceData 是否为空,然后检查 _instanceData.DataSourceType 是否为空,然后是最后一个条件。正如您所说,这只是语法糖,因此您不必编写两个 != null
条件。生成的 IL 代码完全相同,因此是否使用该运算符是一个偏好问题。
在访问深度嵌套的属性时,它确实节省了 space 吨,这是它最有用的地方
if(Parent != null)
{
if(Parent.Child != null)
{
if(Parent.Child.GrandChild != null)
{
Parent.Child.GrandChild.GreatGrandChild.name = "Parent IV";
}
}
}
变成
Parent?.Child?.GrandChild?.GreatGrandChild.name = "Parent IV";
节省了很多space!即使您将所有 ifs 折叠到一个语句中,它仍然可以节省大量的击键和屏幕噪音。
这主要是一道句法sugar/best-practice题。
这是一个有问题的代码示例:
if (_instanceData?.DataSourceType != null && Util.IsEntityBacked(_instanceData.DataSourceType) {// code}
我知道如果 _instanceData 为空,安全导航运算符将继续执行,但在这种情况下,条件中的第一个布尔值是否会按预期进行评估?这是否会成功地对 _instanceData 和 DataSourceType 进行空检查?
另一个例子:
if (LockAcquired && _instanceData?.ObjInfo != null) {// code}
在这种情况下,有可能_instanceData为null,也有可能不是,但ObjInfo为null。仅对对象和 属性 进行老式空检查是更好的做法,还是会按预期完成工作?
编辑:问题最好描述为:
if (obj?.prop != null)
是否等同于
if (obj != null && obj.prop != null)
第一个相当于
if (_instanceData != null && _instanceData.DataSourceType != null && Util.IsEntityBacked(_instanceData.DataSourceType) {// code}
第二个相当于
if (LockAcquired && _instanceData != null && _instanceData.ObjInfo != null) {// code}
所以它会检查 _instanceData 是否为空,然后检查 _instanceData.DataSourceType 是否为空,然后是最后一个条件。正如您所说,这只是语法糖,因此您不必编写两个 != null
条件。生成的 IL 代码完全相同,因此是否使用该运算符是一个偏好问题。
在访问深度嵌套的属性时,它确实节省了 space 吨,这是它最有用的地方
if(Parent != null)
{
if(Parent.Child != null)
{
if(Parent.Child.GrandChild != null)
{
Parent.Child.GrandChild.GreatGrandChild.name = "Parent IV";
}
}
}
变成
Parent?.Child?.GrandChild?.GreatGrandChild.name = "Parent IV";
节省了很多space!即使您将所有 ifs 折叠到一个语句中,它仍然可以节省大量的击键和屏幕噪音。