分享
三行代码  ›  专栏  ›  技术社区  ›  Jake

一个安全的导航操作员可以吗?)用于检查对象是否为空以及属性?

  •  0
  • Jake  · 技术社区  · 3 天前

    这主要是一个语法糖/最佳实践问题。

    下面是一个有问题的代码示例:

    if (_instanceData?.DataSourceType != null && Util.IsEntityBacked(_instanceData.DataSourceType) {// code}
    
    

    我知道如果instanceData为空,safe navigation操作符将继续执行,但在这种情况下,条件中的第一个布尔值是否会按预期计算?这将成功地对instanceData和DataSourceType进行空检查吗?

    另一个例子:

    if (LockAcquired && _instanceData?.ObjInfo != null) {// code}
    

    在这种情况下,可能是_instanceData为空,也可能不是,但ObjInfo为空。只是对对象和属性进行老式的空检查是更好的做法,还是这样做可以如期完成工作?

    编辑:这个问题最好描述为: 是 if (obj?.prop != null) 相当于 if (obj != null && obj.prop != null)

    1 回复  |  直到 2 天前
        1
  •  1
  •   Josh Williard    2 天前

    第一个相当于

    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折叠成一个语句,它仍然可以节省大量的按键和屏幕噪音。