C# 11 移除了一個新特性
在先前的 C# 11 預(yù)覽版本中,C# 11 引入了一個新特性,允許在參數(shù)名稱的末尾加上 !! 來簡化空值檢查(null-checking)。
比如下面這個方法使用傳統(tǒng)的方式進行參數(shù)空值檢查:
public?static?void?M(string s)
{
if (s is?null)
{
throw?new ArgumentNullException(nameof(s));
}
// Body of the method
}使用 !! 語法可以簡寫為:
public?static?void?M(string s!!)
{
// Body of the method
}此簡寫和上面的 if (param is null) throw new ArgumentNullException(...) 是等效的。
但此特性的預(yù)覽版出來后,引起了社區(qū)的很多爭論和反饋(來自于 GitHub 評論、MVP、社交媒體、會議聽眾等)。反對的觀點歸納一下,主要有如下兩種:
引入
!!語法的同時也犧牲了可讀性。在大多數(shù)語言中單個!符號表示取反,數(shù)學(xué)中表示階乘,而用!!表示“不能為空”就顯得有些奇怪。與其引入!!,不如引入一個新的notnull關(guān)鍵字。不管是引入
!!還是notnull作為空值檢查,都會與 NRT (Nullable Reference Types) 產(chǎn)生沖突,因為在 NRT 中本身就可以添加嚴(yán)格的空值檢查。
微軟 C# 團隊表示感謝所有的反饋,社區(qū)的反饋使團隊的洞察更廣泛,將重新考慮是否在 C# 11 中引入這個新特性。但由于團隊沒有足夠的信心認(rèn)為這個特性是 C# 正確的功能設(shè)計,因此決定將其從 C# 11 中刪除,在將來的版本中可能還會繼續(xù)探討這個話題,引入更好的設(shè)計。
雖然移除了 !! 特性,但有好幾種有效的方式可以用一行代碼來進行空值檢查。如果你使用的是 .NET 6,建議使用 ArgumentNullException.ThrowIfNull 方法:
public?static?void?M(string myString)
{
ArgumentNullException.ThrowIfNull(myString);
// method
}使用 ThrowIfNull 方法的好處之一是它使用 CallerArgumentExpression 來自動在異常消息中包含參數(shù)名稱:
System.ArgumentNullException: 'Value cannot be null. (Parameter 'myString')'附:關(guān)于移除 !! 特性的官方博文:
https://devblogs.microsoft.com/dotnet/csharp-11-preview-updates/