https://www.cnblogs.com/minotauros/archive/2020/02/29/12384792.htmlhtml
在C#6及以上版本中,加入了一項特別好用的運算符:Null條件運算符?.和?[]能夠用來方便的執行判空操做,當運算符左側操做數不爲null時纔會進行訪問操做,不然直接返回null。這極大的簡化的判空代碼的書寫,但在使用過程當中仍然須要注意一些問題,以避免其帶來咱們意想不到的後果。函數
例如博主在使用Unity遊戲引擎時便遇到使用下面代碼依然會拋出空引用異常的狀況:this
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編譯器對該運算符的實現提及。spa
查看以上代碼中Start()函數的IL代碼:code
能夠發如今IL_0008中會判斷字段myMonoBehaviour是否爲空,若是非空,則跳轉到IL_000d執行調用實例方法Foo(),不然跳轉到IL_0013行返回。這裏的判空只是進行按位來判斷是否爲空,然而在Unity遊戲引擎中,MonoBehaviour繼承自UnityEngine.Object,其重寫了==和!=運算符,所以按位執行判空操做顯然是沒法知足要求的,當其引用的物體被銷燬而該引用依然保存的時候,就會在調用gameObject屬性時拋出異常。htm
此時,使用正常的判空操做則會避免這個問題:對象
public void OnEnable() { if (this.myMonoBehaviour != null) { this.myMonoBehaviour?.Foo(); } }
所以,在使用Null條件運算符時,須要特別注意操做數所指向對象的運行時類型是否重寫了==和!=運算符,若是重寫了這些運算符,那麼就儘可能不能使用Null條件運算符,而應該使用傳統的判空方式。blog
若是您以爲閱讀本文對您有幫助,請點一下「推薦」按鈕,您的承認是我寫做的最大動力!繼承
做者:Minotauros
出處:https://www.cnblogs.com/minotauros/
遊戲
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。