詳解C#中檢查null的語法糖
今天看到已經(jīng)更新了devblogs,新增的C# 11的!!(用于檢查null的語法)經(jīng)過非常長的討論,最后取消了。然后我又想起來null檢查,這個可以說一說。
函數(shù)參數(shù)null檢查
傳統(tǒng)寫法
寫一個函數(shù)的時候,最經(jīng)典的檢查,估計也是大家最常使用的null檢查,應該是這樣的吧:
public static void GetV1(string prompt)
{
if (prompt is null) throw new ArgumentNullException(nameof(prompt));
Console.WriteLine(prompt);
}
ThrowIfNull
這個寫起來也沒啥問題,但是總覺得有點不舒適。.NET 6在ArgumentNullException中新增了ThrowIfNull方法,可以寫的更優(yōu)雅一點。
public static void GetV2(string prompt)
{
ArgumentNullException.ThrowIfNull(prompt);
Console.WriteLine(prompt);
}
異常的時候,就會出現(xiàn):System.ArgumentNullException: 'Value cannot be null. (Parameter 'prompt')'。這個是不是簡單了點?可是還是需要寫一行。
C# 11的!!語法(已經(jīng)取消)
C# 11剛preview的時候,我就瞄到了這個特性,現(xiàn)在依然可以通過設置preview來進行啟用,但是以后正式發(fā)布估計就不行了。
它通過在參數(shù)后面疊加!!表示此參數(shù)不可為空,運行時會自動進行檢查,如果是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);
}
這樣大家就可以專注于業(yè)務代碼,不需要經(jīng)??紤]異常檢查了。至于為什么這個東西最后還是被刪除了,可以從討論中看到一絲端倪,首先是感覺非常糾結(jié)于這個語法,兩個嘆號;然后就是已經(jīng)有比較多的方式可以實現(xiàn)檢查了,這個東西是否有必要。反正最終是以后再討論了,不過也可以看出來C#語言工作組對語言的特性討論非常謹慎。
他們還討論了很多別的形式,每種都提出了各自的優(yōu)缺點挺有意思的,能看出來有一點設計語言的嚴謹和小強迫癥在,點贊~
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,那么返回右邊的操作數(shù),否則就返回左邊的操作數(shù),這個在給變量賦予默認值非常好用。
int? a = null; int b = a ?? -1; Console.WriteLine(b); // output: -1
??=
當左邊是null,那么就對左邊的變量賦值成右邊的
int? a = null; a ??= -1; Console.WriteLine(a); // output: -1
?.
當左邊是null,那么不執(zhí)行后面的操作,直接返回空,否則就返回實際操作的值。
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結(jié)果,不會繼續(xù)計算。下面兩個操作會有不同的結(jié)果。
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.
}
}
一些操作
//參數(shù)給予默認值
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的時候,依然執(zhí)行代碼
if(obj != null)
obj.Act();
//替換
obj?.Act();
//Dictionary取值與賦值
string result;
if(dict.ContainKey(key))
{
if(dict[key] == null) result = "有結(jié)果為null";
else result = dict[key];
}
else
result = "無結(jié)果為null";
//替換
var result= dict.TryGetValue(key, out var value) ? value ?? "有結(jié)果為null" : "無結(jié)果為null";
結(jié)語
原來新定的C# 11提供了一個新的??,話說我個人還是挺喜歡這個特性的,不管以什么形式出現(xiàn)吧,期待以后再見。
C#中為了處理null給我們準備了許多的語法糖,只能說非常簡便了。有很多人會說這個可讀性不好,或者覺得這是“茴字的幾種寫法”似的歪門邪道,我只能說,傳統(tǒng)的語法也不是說取消了,語言有發(fā)展,只要還是比較審慎的,我覺得還是一件好事。
到此這篇關于詳解C#中檢查null的語法糖的文章就介紹到這了,更多相關C#檢查null內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C#創(chuàng)建數(shù)據(jù)庫及導入sql腳本的方法
這篇文章主要介紹了C#創(chuàng)建數(shù)據(jù)庫及導入sql腳本的方法,涉及C#針對數(shù)據(jù)庫的創(chuàng)建、連接、導入等相關操作技巧,需要的朋友可以參考下2015-12-12
C# WinForm創(chuàng)建Excel文件的實例
下面小編就為大家?guī)硪黄狢# WinForm創(chuàng)建Excel文件的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01
C#中Invoke和BeginInvoke區(qū)別小結(jié)
有時候,我們不得不跨線程調(diào)用主界面的控件來進行操作,所以為了方便的解決問題,.net為我們提供了Invoke?與beginInvoke,那么Invoke和BeginInvoke區(qū)別在哪,本文就來詳細的介紹一下2023-08-08

