網站首頁 編程語言 正文
今天看到已經更新了devblogs,新增的C# 11的!!(用于檢查null的語法)經過非常長的討論,最后取消了。然后我又想起來null檢查,這個可以說一說。
函數參數null檢查
傳統寫法
寫一個函數的時候,最經典的檢查,估計也是大家最常使用的null檢查,應該是這樣的吧:
public static void GetV1(string prompt) { if (prompt is null) throw new ArgumentNullException(nameof(prompt)); Console.WriteLine(prompt); }
ThrowIfNull
這個寫起來也沒啥問題,但是總覺得有點不舒適。.NET 6在ArgumentNullException
中新增了ThrowIfNull
方法,可以寫的更優雅一點。
public static void GetV2(string prompt) { ArgumentNullException.ThrowIfNull(prompt); Console.WriteLine(prompt); }
異常的時候,就會出現:System.ArgumentNullException: 'Value cannot be null. (Parameter 'prompt')'
。這個是不是簡單了點?可是還是需要寫一行。
C# 11的!!語法(已經取消)
C# 11剛preview的時候,我就瞄到了這個特性,現在依然可以通過設置preview來進行啟用,但是以后正式發布估計就不行了。
它通過在參數后面疊加!!表示此參數不可為空,運行時會自動進行檢查,如果是null就直接彈出錯誤。
public static void GetV3(string prompt!!) { Console.WriteLine(prompt); }
這個代碼會被編譯器翻譯成:
public static void GetV3(string prompt!!) { if (prompt is null) { throw new ArgumentNullException(nameof(prompt)); } Console.WriteLine(prompt); }
這樣大家就可以專注于業務代碼,不需要經常考慮異常檢查了。至于為什么這個東西最后還是被刪除了,可以從討論中看到一絲端倪,首先是感覺非常糾結于這個語法,兩個嘆號;然后就是已經有比較多的方式可以實現檢查了,這個東西是否有必要。反正最終是以后再討論了,不過也可以看出來C#語言工作組對語言的特性討論非常謹慎。
他們還討論了很多別的形式,每種都提出了各自的優缺點挺有意思的,能看出來有一點設計語言的嚴謹和小強迫癥在,點贊~
void M(string s!!); void M(string! s); void M(string s!); void M(notnull string s); void M(string s ?? throw); void M(string s is not null); void M(checked string s); void M(string s) where s is not null;
有關null的一些操作
說起這個,就順便說說c#處理null的另外幾個語法糖吧。
??
如果左邊是的null,那么返回右邊的操作數,否則就返回左邊的操作數,這個在給變量賦予默認值非常好用。
int? a = null; int b = a ?? -1; Console.WriteLine(b); // output: -1
??=
當左邊是null,那么就對左邊的變量賦值成右邊的
int? a = null; a ??= -1; Console.WriteLine(a); // output: -1
?.
當左邊是null,那么不執行后面的操作,直接返回空,否則就返回實際操作的值。
using System; public class C { public static void Main() { string i = null; int? length = i?.Length; Console.WriteLine(length ?? -1); //output: -1 } }
?[]
索引器操作,和上面的操作類似
using System; public class C { public static void Main() { string[] i = null; string result = i?[1]; Console.WriteLine(result ?? "null"); // output:null } }
注意,如果鏈式使用的過程中,只要前面運算中有一個是null,那么將直接返回null結果,不會繼續計算。下面兩個操作會有不同的結果。
using System; public class C { public static void Main() { string[] i = null; Console.WriteLine(i?[1]?.Substring(0).Length); //不彈錯誤 Console.WriteLine((i?[1]?.Substring(0)).Length) // System.NullReferenceException: Object reference not set to an instance of an object. } }
一些操作
//參數給予默認值 if(x == null) x = "str"; //替換 x ??= "str"; //條件判斷 string x; if(i<3) x = y; else { if(z != null) x = z; else z = "notnull"; } //替換 var x = i < 3 ? y : z ?? "notnull" //防止對象為null的時候,依然執行代碼 if(obj != null) obj.Act(); //替換 obj?.Act(); //Dictionary取值與賦值 string result; if(dict.ContainKey(key)) { if(dict[key] == null) result = "有結果為null"; else result = dict[key]; } else result = "無結果為null"; //替換 var result= dict.TryGetValue(key, out var value) ? value ?? "有結果為null" : "無結果為null";
結語
原來新定的C# 11提供了一個新的??,話說我個人還是挺喜歡這個特性的,不管以什么形式出現吧,期待以后再見。
C#中為了處理null給我們準備了許多的語法糖,只能說非常簡便了。有很多人會說這個可讀性不好,或者覺得這是“茴字的幾種寫法”似的歪門邪道,我只能說,傳統的語法也不是說取消了,語言有發展,只要還是比較審慎的,我覺得還是一件好事。
原文鏈接:https://www.cnblogs.com/podolski/p/16184027.html
相關推薦
- 2022-12-12 Kotlin構造函數與成員變量和init代碼塊執行順序詳細講解_Android
- 2022-08-02 goFrame的gqueue與channe的區別_Golang
- 2022-03-07 golang強制類型轉換和類型斷言_Golang
- 2022-02-26 微信小程序 - 將頁面可分享到朋友圈功能(兩步完成)
- 2022-12-10 docker編譯IJKPlayer播放器記錄詳解_docker
- 2024-04-03 @ExceptionHandler沒有報錯詳細信息
- 2022-11-12 Redis主從復制操作和配置詳情_Redis
- 2022-06-06 基于VSTS的Xamarin.Android持續集成步驟詳解_Android
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支