使用C#的null條件運算符?.的注意事項


Introduction:

  在C#6及以上版本中,加入了一項特別好用的運算符:Null條件運算符?.和?[]可以用來方便的執行判空操作,當運算符左側操作數不為null時才會進行訪問操作,否則直接返回null。這極大的簡化的判空代碼的書寫,但在使用過程中仍然需要注意一些問題,以免其帶來我們意想不到的后果。

  例如博主在使用Unity游戲引擎時便遇到使用下面代碼依然會拋出空引用異常的情況:

using UnityEngine;

public class MyMonoBehaviour : MonoBehaviour
{
    public MyMonoBehaviour myMonoBehaviour;

    public void Start()
    {
        this.myMonoBehaviour?.Foo();
    }

    public void Foo()
    {
        Debug.Log(this.gameObject.name);
    }
}

  為什么使用了Null條件運算符還會出現空引用異常的情況,這需要從.Net編譯器對該運算符的實現說起。

Body:

  查看以上代碼中Start()函數的IL代碼:

  

   可以發現在IL_0008中會判斷字段myMonoBehaviour是否為空,如果非空,則跳轉到IL_000d執行調用實例方法Foo(),否則跳轉到IL_0013行返回。這里的判空只是進行按位來判斷是否為空,然而在Unity游戲引擎中,MonoBehaviour繼承自UnityEngine.Object,其重寫了==和!=運算符,因此按位執行判空操作顯然是無法滿足要求的,當其引用的物體被銷毀而該引用依然保存的時候,就會在調用gameObject屬性時拋出異常。

  此時,使用正常的判空操作則會避免這個問題:

    public void OnEnable()
    {
        if (this.myMonoBehaviour != null)
        {
            this.myMonoBehaviour?.Foo();
        }
    }

Conclusion:

  因此,在使用Null條件運算符時,需要特別注意操作數所指向對象的運行時類型是否重寫了==和!=運算符,如果重寫了這些運算符,那么就盡量不能使用Null條件運算符,而應該使用傳統的判空方式。

 


 如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的認可是我寫作的最大動力!

作者:Minotauros
出處:https://www.cnblogs.com/minotauros/

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM