这主要是一个语法糖/最佳实践问题。
下面是一个有问题的代码示例:
if (_instanceData?.DataSourceType != null && Util.IsEntityBacked(_instanceData.DataSourceType) {// code}
我知道如果_instanceData为 null,安全导航运算符将继续执行,但在这种情况下,条件中的第一个布尔值是否会按预期进行评估? 这会在_instanceData和数据源类型上成功进行空检查吗?
再比如:
if (LockAcquired && _instanceData?.ObjInfo != null) {// code}
在这种情况下,_instanceData可能为空,也可能不是,但 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 代码完全相同,因此是否使用运算符是一个首选项问题。
在访问深度嵌套属性时,它确实节省了大量空间,这是它最有用的地方。
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";
节省大量空间!即使您将所有 ifs 折叠到一个语句中,它仍然会节省大量击键和屏幕噪音。