今天看到已經更新了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的時候,我就瞄到了這個特性,現在依然可以通過設定
它通過在引數后面疊加!!表示此引數不可為空,運行時會自動進行檢查,如果是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://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and-
- https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/null-coalescing-operator
后記
一定要夸一下博客園,寫完這篇文章想登陸博客園發布的時候,被登陸卡住了,彈出來和google一樣的驗證畫面,找紅綠燈找人行橫道什么的,只能說我找了幾分鐘也沒找明白,我確信我已經點的正確了,所有的區塊,占上了有一點算不算?不知道也沒有反饋,就點呀點呀,密碼我已經按照要求設定的夠復雜了,還有必要通過這種反人類的東西來驗證嗎?不理解,京東阿里之類的購物網站的驗證也就拖一下完事,這博客園的后臺估計比那些個地方還要敏感吧,贊一個!太贊了!
除非特殊說明,本作品由podolski創作,采用知識共享署名 4.0 國際許可協議進行許可,歡迎轉載,轉載請保留原文鏈接~喜歡的觀眾老爺們可以點下關注或者推薦~轉載請註明出處,本文鏈接:https://www.uj5u.com/net/462816.html
標籤:C#
上一篇:RforceNetwork-啟用縮放時如何將圖例保留在左上角?
下一篇:CNC檔案版本管理NC檔案審核CNC程式檔案比對NC程式檔案版本管理CNC程式檔案生命周期管理NC檔案生命周期管理
