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/
本文著作權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/67183.html
標籤:C#
上一篇:使用HtmlAgilityPack開發爬蟲篩選HTML時,關于xpath的坑
下一篇:C#面向物件--屬性
