C# 9 新特性 —— 补充篇
C# 9 新特性 —— 補充篇
Intro
前面我們分別介紹了一些 C# 9 中的新特性,還有一些我覺得需要了解一下的新特性,寫一篇作為補充。
Top-Level Statements
在以往的代碼里,一個應用程序必須要有 Main 方法才能運行,從 C# 9 開始,支持沒有 Main 方法的程序,實際編譯之后還是會有一個 Main 方法的,使用示例如下:
using?static?System.Console;WriteLine("Hello?World!");實際編譯出來的結果如下:
實際會生成一個沒有命名空間的 <Program>$ 的類型,類中定義的有一個名稱是 <Main>$ 的靜態方法
Improved discards in lambda input parameter
從 C# 7.2 開始,我們可以使用 _ 來代表一個不使用的變量,廢棄變量,但是在 lambda 表達式里默認不能有同名的參數名,從 C# 9 開始,支持多個參數同時使用 _ 來表示,如下所示:
Func<int,?int,?int>?constant?=?(_,?_)?=>?42;Attributes for local function
從 C# 9 開始,我們可以在局部方法(本地方法)上設置 Attribute
public?static?void?MainTest() {InnerTest();[MethodImpl(MethodImplOptions.Synchronized)]void?InnerTest(){Console.WriteLine(nameof(InnerTest));} }Partition methods
在 C# 2.0 之后就支持了分部類,通常分部類會出現在動態代碼生成的地方,對于想要將一個類型拆分到多個文件里,我們通常也會考慮用到分部類。
C# 3.0 開始支持了分部方法,但是功能比較弱,使用起來有一些限制:
分部類型各部分中的簽名必須匹配。
方法必須返回 void。
不允許使用訪問修飾符。分部方法是隱式 private 的。
C# 9 增強了分部方法的支持,分部方法的使用,只能在一個地方有方法體,目前主要是為了 Source Generator 引入了這個語言特性,可以在一個地方定義方法,在另外一個地方實現方法體,示例如下:
partial?class?PartialMethod {public?static?partial?void?MainTest();static?partial?void?Test1(); }partial?class?PartialMethod {public?static?partial?void?MainTest(){Test1();Console.WriteLine("Partial?method?works");} }符合 C# 3.0 分部方法規則的允許沒有方法體,否則必須要有方法體
ModuleInitializer
Source Generator 除了上面的分部方法之外,還引入了一個 ModuleInitializer 的概念,就像它的名字,模塊初始化器,當用到某個模塊的時候就會調用對應的 ModuleInitializer 方法進行初始化操作
ModuleInitializer 定義如下:
namespace?System.Runtime.CompilerServices {[AttributeUsage(AttributeTargets.Method,?Inherited?=?false)]public?sealed?class?ModuleInitializerAttribute?:?Attribute{} }使用示例如下:
internal?static?class?ModuleInitializerSample {///?<summary>///?Initializer?for?specific?module///?///?Must?be?static///?Must?be?parameter-less///?Must?return?void///?Must?not?be?a?generic?method///?Must?not?be?contained?in?a?generic?class///?Must?be?accessible?from?the?containing?module///?</summary>[ModuleInitializer]public?static?void?Initialize(){Console.WriteLine($"{nameof(ModuleInitializerAttribute)}?works");} }ModuleInitlializer 對應的方法有幾個要求
必須是靜態方法
不能有方法參數,無參數方法
方法沒有返回值,返回類型必須是 void
不能是泛型方法
不能在泛型類中
必須能夠被所在模塊訪問的到(至少是 internal)
來看反編譯的代碼,可以看到有一個 Module 的類,在這個 Module 類的靜態構造方法里會去調用聲明為 ModuleInitializer 的方法
Function Pointer
C# 9 支持方法指針,對委托進一步的”C++化“,進一步提升性能,屬于非安全代碼,使用需開啟 unsafe,使用示例如下:
public?static?unsafe?void?MainTest() {delegate*<int,?int,?int>?pointer?=?&Test;var?result?=?pointer(1,?1);Console.WriteLine(result); }private?static?int?Test(int?num1,?int?num2) {Console.WriteLine($"Invoke?in?{nameof(Test)},?{num1}_{num2}");return?num1?+?num2; }Static Anoymouse Method
C# 9 開始支持在匿名方法或者表達式前聲明 static,聲明 static 之后就不能使用實例變量,只能使用靜態變量,如下所示:
internal?class?StaticAnonymousMethod {private?readonly?int?num?=?1;public?void?MainTest(){//?anonymous?methodAction?action?=?()?=>?{?Console.WriteLine(num);?};Action?action1?=?static?()?=>?{?};//?can?not?access?`num`//expressionExpression<Func<int,?bool>>?expression?=?i?=>?i?>?num;Expression<Func<int,?bool>>?expression1?=?static?i?=>?i?>?1;//?can?not?access?`num`} }Covariant Return Type
C# 9 開始支持返回類型的 Covariant(協變), 對于 override 方法可返回從重寫基方法的返回類型派生的類型。這對于record和其他支持工廠方法的類型會很有用。可以參考下面的使用示例:
internal?class?CovariantReturnType {private?abstract?class?Operation{}private?abstract?class?OperationFactory{public?abstract?Operation?GetOperation();}private?class?AddOperation?:?Operation{}private?class?AddOperationFactory?:?OperationFactory{//?返回類型協變,返回具體的類型而不是抽象類中聲明的類型public?override?AddOperation?GetOperation(){return?new();}}public?static?void?MainTest(){var?factory?=?new?AddOperationFactory();factory.GetOperation();} }More
除此之外還有一些小的更新特性,詳細可以參考文末給出的官方文檔。
Reference
https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9
https://github.com/WeihanLi/SamplesInPractice/tree/master/CSharp9Sample
總結
以上是生活随笔為你收集整理的C# 9 新特性 —— 补充篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Asp.Net Core使用Skywal
- 下一篇: C# 中的 null 包容运算符 “!”