介紹
C# 11 將引入一個新的運算符! 簡化代碼中參數的空檢查。 該版本已經支持此語法。 如果您有興趣,不妨嘗試一下。 我們來看看如何使用它。
如果想在本地代碼中編譯測試,需要安裝.NET 7 1 SDK,下載地址:然后在本地創建一個控制臺應用程序,可以使用命令new來創建,手動修改項目文件,配置C#語言版本為,添加如下:
<Project?Sdk="Microsoft.NET.Sdk">
??<PropertyGroup>
????<OutputType>ExeOutputType>
????<Targetframework>net7.0Targetframework>????
????<ImplicitUsings>enableImplicitUsings>
????<Nullable>enableNullable>
+???<LangVersion>previewLangVersion>
??PropertyGroup>
Project>
!! 是一個new運算符,將其添加到參數后編譯器會自動生成一段空檢查代碼
嘭嘭
我們來嘗試一下,測試代碼如下:
Hello("World");
try
{
????Hello(null!);
}
catch?(Exception?ex)
{
????Console.WriteLine(ex);
}
void?Hello(string?name!!)
{
????Console.WriteLine($"Hello,?{name}!");
}
運行run執行代碼,可以看到類似如下的輸出:
可以看到,當傳遞null時,會拋出n異常,說明確實做了null檢查
該運算符不僅適用于方法參數,還適用于委托參數、索引器等。
什么是
從上面的輸出中,我們可以看到存在空檢查。 它實際上是什么樣子的? 我們可以反編譯代碼,看看實際生成的代碼是什么樣的。 反編譯結果如下:
類型和Main方法由編譯器自動生成,是C#9引入的頂級語句(Top-Level)
可以看到我們代碼中的Hello方法不見了,多了一個編譯器生成的方法。 是我們原來方法的變形,只增加了一行代碼。
<PrivateImplementationDetails>.ThrowIfNull(name,?"name");
我們再看一下實現,如下:
可以看到這里實現了null檢查。 如果參數為null,則會拋出n異常。 相信大家都知道它是如何實現的。 那么就有一個問題需要思考。 這里我們使用一個方法。 如果有兩個這樣的方法會是什么樣子?
這個類會生成兩個嗎?我們來試試吧,我們把這個方法復制一下,改個名字,反編譯一下
void?Hello1(string?name!!)?=>?Console.WriteLine($"Hello,?{name}!");
反編譯結果如下:
可以看到實際上調用的是同一個方法,
這個類型只生成一次,那么如果這兩個方法在兩個項目中怎么辦? 你可以自己嘗試一下~~
更多的
使用該運算符時,有一些注意事項。 如果啟用可為空引用類型并將參數聲明為可為空引用類型,編譯器會產生警告,因為它實際上不應該為 null,為 null 會拋出異常,因此編譯器會發出警告,示例為如下:
//?warning?CS8995:?Nullable?type?'string?'?is?null-checked?and?will?throw?if?null.//?void?Hello2(string??name!!)?=>?Console.WriteLine($"Hello,?{name}!");
值類型不能使用該運算符,因為值類型不會為null,編譯器會直接報錯,但可為null的值類型是可以的,例如:
//?error?CS8992:?Parameter?'int'?is?a?non-nullable?value?type?and?cannot?be?null-checked.//?void?Hello3(int?name!!)?=>?Console.WriteLine($"Hello,?{name}!");
另外,out參數不能使用該運算符,如:
//?error?CS8994:?'out'?parameter?'name'?cannot?be?null-checked.//?void?Hello4(out?string?name!!)?=>?name?=?"World";
想要嘗試的朋友可以安裝.NET 7 1來體驗。 如果他們不想安裝,也可以通過在線網站體驗編譯器的新功能
.NET中的代碼已經使用了這個new運算符來簡化參數的null檢查,可以參考:
- 結束符 -