1. 程式人生 > >C# 9.0 終於來了, Top-level programs 和 Partial Methods 兩大新特性探究

C# 9.0 終於來了, Top-level programs 和 Partial Methods 兩大新特性探究

## 一:背景 ### 1. 講故事 .NET 5 終於在 6月25日 釋出了第六個預覽版,隨之而來的是更多的新特性加入到了 C# 9 Preview 中,這個系列也可以繼續往下寫了,廢話不多說,今天來看一下 `Top-level programs` 和 `Extending Partial Methods` 兩大新特性。 ### 2. 安裝必備 下載最新的 `.net 5 preview 6`。 ![](https://img2020.cnblogs.com/other/214741/202006/214741-20200627115156431-863143496.png) 下載最新的 ` Visual Studio 2019 version 16.7 Preview 3.1` ![](https://img2020.cnblogs.com/other/214741/202006/214741-20200627115156661-2080301966.png) ## 二:新特性研究 ### 1. Top-level programs 如果大家玩過 python,應該知道在 xxx.py 中寫一句 print,這程式就能跑起來了,簡單高效又粗暴,很開心的是這特性被帶到了C# 9.0 中。 * 修改前 ``` C# using System; namespace ConsoleApp2 { class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); } } ``` * 修改後 ``` C# System.Console.WriteLine("Hello World!"); ``` ![](https://img2020.cnblogs.com/other/214741/202006/214741-20200627115156855-1397999152.png) 這就有意思了,Main入口函式去哪了? 沒它的話,JIT還怎麼編譯程式碼呢? 想知道答案的話用 ILSpy 反編譯看一下就好啦! ``` C# .class private auto ansi abstract sealed beforefieldinit $Program extends [System.Runtime]System.Object { .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) // Methods .method private hidebysig static void $Main ( string[] args ) cil managed { // Method begins at RVA 0x2050 // Code size 18 (0x12) .maxstack 8 .entrypoint IL_0000: ldstr "Hello World!" IL_0005: call void [System.Console]System.Console::WriteLine(string) IL_000a: nop IL_000b: call string [System.Console]System.Console::ReadLine() IL_0010: pop IL_0011: ret } // end of method $Program::$Main } // end of class $Program ``` 從 IL 上看,類變成了 `$Program`, 入口方法變成了 `$Main`, 這就好玩了,在我們的印象中入口函式必須是 `Main`,否則編譯器會給你一個大大的錯誤,你加了一個 $ 符號,那CLR還能認識嗎? 能不能認識我們用 windbg 看一些託管和非託管堆疊,看看有什麼新發現。 ``` C# 0:010> ~0s ntdll!NtReadFile+0x14: 00007ffe`f8f8aa64 c3 ret 0:000> !dumpstack OS Thread Id: 0x7278 (0) Current frame: ntdll!NtReadFile + 0x14 Child-SP RetAddr Caller, Callee 0000008551F7E810 00007ffed1e841dc (MethodDesc 00007ffe4020d500 + 0x1c System.Console.ReadLine()), calling 00007ffe400ab090 0000008551F7E840 00007ffe4014244a (MethodDesc 00007ffe401e58f0 + 0x3a $Program.$Main(System.String[])), calling 00007ffe40240f58 0000008551F7E880 00007ffe9fcc8b43 coreclr!CallDescrWorkerInternal + 0x83 [F:\workspace\_work\1\s\src\coreclr\src\vm\amd64\CallDescrWorkerAMD64.asm:101] 0000008551F7E8C0 00007ffe9fbd1e03 coreclr!MethodDescCallSite::CallTargetWorker + 0x263 [F:\workspace\_work\1\s\src\coreclr\src\vm\callhelpers.cpp:554], calling coreclr!CallDescrWorkerWithHandler [F:\workspace\_work\1\s\src\coreclr\src\vm\callhelpers.cpp:56] 0000008551F7E950 00007ffe9fb8c4e5 coreclr!MethodDesc::IsVoid + 0x21 [F:\workspace\_work\1\s\src\coreclr\src\vm\method.cpp:1098], calling coreclr!MetaSig::IsReturnTypeVoid [F:\workspace\_work\1\s\src\coreclr\src\vm\siginfo.cpp:5189] 0000008551F7EA00 00007ffe9fb8c4bf coreclr!RunMainInternal + 0x11f [F:\workspace\_work\1\s\src\coreclr\src\vm\assembly.cpp:1488], calling coreclr!MethodDescCallSite::CallTargetWorker [F:\workspace\_work\1\s\src\coreclr\src\vm\callhelpers.cpp:266] 0000008551F7EB30 00007ffe9fb8c30a coreclr!RunMain + 0xd2 [F:\workspace\_work\1\s\src\coreclr\src\vm\assembly.cpp:1559], calling coreclr!RunMainInternal [F:\workspace\_work\1\s\src\coreclr\src\vm\assembly.cpp:1459] ``` 從上面堆疊的流程圖看: `coreclr!RunMain` -> `coreclr!MethodDesc` -> `coreclr!CallDescrWorkerInternal` -> `$Program.$Main`, 確實被呼叫了,不過有一個重大發現,在 `$Program.$Main` 呼叫之前底層的 CLR 讀取了 方法描述符,這就是一個重大突破點,方法描述符在哪裡呢? 可以用 ildasm 去看一下元資料列表。 ![](https://img2020.cnblogs.com/other/214741/202006/214741-20200627115157087-1531887950.png) 可以看到,入口函式那裡打上了一個 `ENTRYPOINT` 標記,這就說明入口函式名其實是可以隨便更改的,只要被 `ENTRYPOINT`打上標記即可,CoreCLR就能認的出來~~~ ### 2. Partial Methods 我們知道 部分方法 是一個很好的樁函式,而且在 C# 3.0 中就已經實現了,那時候給我們增加了很多限制,如下圖: ![](https://img2020.cnblogs.com/other/214741/202006/214741-20200627115157339-1849012727.png) 翻譯過來就是: * 部分方法的簽名必須一致 * 方法必須返回void * 不允許使用訪問修飾符,而且還是隱式私有的。 在 C# 9.0 中放開了對 方法簽名 的所有限制,正如 issue 總結: ![](https://img2020.cnblogs.com/other/214741/202006/214741-20200627115157758-512258283.png) 這是一個非常好的訊息,現在你的部分方法上可以加上各種型別的返回值啦,這裡我舉一個例子: ``` C# class Program { static void Main(string[] args) { var person = new Person(); Console.WriteLine(person.Run("jack")); } } public partial class Person { public partial string Run(string name); } public partial class Person { public partial string Run(string name) => $"{name}:開溜了~"; } ``` ![](https://img2020.cnblogs.com/other/214741/202006/214741-20200627115157947-1845804783.png) 然後我們用 ILSpy 簡單看看底層怎麼玩的,如下圖可以看到其實就是一個簡單的合成,對吧。 ![](https://img2020.cnblogs.com/other/214741/202006/214741-20200627115158147-2129369286.png) 現在我有想法了,如果我不給 Run 方法實現會怎麼樣? 把下面的 partial 類註釋掉看一下。 ![](https://img2020.cnblogs.com/other/214741/202006/214741-20200627115158416-1759302006.png) 從報錯資訊看,可訪問的修飾符必須要有方法實現,還以為直接編譯的時候抹掉呢。 這就起不到樁函式的作用:-D,不過這個特性還是給了我們更多的可能用的到的應用場景吧。 ## 三:總結 本篇兩個特性還是非常實用的,Top-level programs 讓我們可以寫更少的程式碼,甚至拿起 記事本 都可以快捷的編寫類似一次性使用的測試程式碼, Partial Methods 特性留給大家補充吧,我基本上算是沒用過 (┬_┬)。 ### 如您有更多問題與我互動,掃描下方進來吧~

相關推薦

C# 9.0 終於, Top-level programs Partial Methods 特性探究

## 一:背景 ### 1. 講故事 .NET 5 終於在 6月25日 釋出了第六個預覽版,隨之而來的是更多的新特性加入到了 C# 9 Preview 中,這個系列也可以繼續往下寫了,廢話不多說,今天來看一下 `Top-level programs` 和 `Extending Partial Meth

C#9.0 終於,您還學的動嗎? 帶上VS一起解讀吧!

## 一:背景 ### 1. 講故事 好訊息,`.NET 5.0` 終於在2020年6月10日釋出了第五個預覽版,眼尖的同學一定看到了在這個版本中終於支援了 `C# 9.0`,此處有掌聲,太好了!!! [.Net5官方連結]( https://dotnet.microsoft.com/downl

C#9.0 終於,帶你一起解讀Pattern matching nint 特性玩法

## 一:背景 ### 1. 講故事 上一篇跟大家聊到了`Target-typed new` 和 `Lambda discard parameters`,看部落格園和公號裡的閱讀量都達到了新高,甚是欣慰,不管大家對新特性是多頭還是空頭,起碼還是對它抱有一種極為關注的態度,所以我的這個系列還得跟,那就繼

C#9.0 終於,帶你一起解讀 nint Pattern matching 特性玩法

## 一:背景 ### 1. 講故事 上一篇跟大家聊到了`Target-typed new` 和 `Lambda discard parameters`,看部落格園和公號裡的閱讀量都達到了新高,甚是欣慰,不管大家對新特性是多頭還是空頭,起碼還是對它抱有一種極為關注的態度,所以我的這個系列還得跟,那就繼

快醒醒,C# 9 中又一堆關鍵詞 init,record,with

## 一:背景 ### 1. 講故事 .NET5 終於在 2020-08-25 也就是大前天釋出了第八個預覽版,這麼多的預覽版搞得我都麻木了,接踵而來的就是更多的新特性加入到了 C# 9 中,既然還想呆在這條船上,得繼續硬著頭皮學習哈,這一篇跟大家聊聊新增的幾個關鍵詞。 ## 二:新增關鍵詞

IOS UIAlertController 彈框 (ios 9.0 後代替UIAlertView彈框 UIActionSheet下彈框)

[摘要:正在IOS 9.0 後 蘋果沒有 UIActionSheet 由UIAlertController取代二者 用操縱器將二者開兩為一 很簡略 輕易] 在IOS 9.0 後 蘋果官方宣佈不再或不推薦使用UIAlertView 和 UIActionSheet 由UIAle

Qt:終於!基於QMLWebGL開發網頁端

序言 Qt早在今年2月,就釋出了WebGL相關的blog http://blog.qt.io/blog/2017/02/22/qt-quick-webgl-streaming/ 並且預計5.10加入這個feature 10個月過去了,Qt在12月7號如約

JDK15就要,你卻還不知道JDK8的特性

> 微信搜「煙雨星空」,白嫖更多好文。 現在 Oracle 官方每隔半年就會出一個 JDK 新版本。按時間來算的話,這個月就要出 JDK15 了。然而,大部分公司還是在使用 JDK7 和 8 。 之前去我朋友家,竟然被嘲笑不會用 JDK8 。 不服氣的我,回來之後,當然是重點學習之啊。 ![](h

C#9.0特性詳解系列之四:頂級程式語句(Top-Level Programs)

## 1 背景與動機 通常,如果只想用C#在控制檯上列印一行“Hello World!”,這可不是Console.WriteLine("Hello World!");一條語句就可以搞定的,還涉及到其他必要基礎程式碼(如定義類和入口函式Main),例如下面: ```C# using System; clas

iw14.0.50終於可以直接在地址欄輸入url打開iw功能頁面;可以自由使用EasyUI等js框架;顯示模式對話框也不再七繞八繞惹人煩

protect nbsp library easy 我認 發出 pst 是的 orm 示例代碼已經放出!請移步使用delphi+intraweb進行微信開發1~4代碼示例進行下載,雖為示例代碼但是是從我項目中移出來的,封裝很完備適於自行擴展和修改。 iw14.0.5

圖床「神器」PicGo v2.0更新,外掛系統終於

前言 距離上次更新(v1.6.2)已經過去了5個月,很抱歉2.0版本來得這麼晚。本來想著在18年12月(PicGo一週年的時候)釋出2.0版本,但是無奈正值研究生開題期間,需要花費不少時間(不然畢不了業了T T),所以這個大版本姍姍來遲。不過從這個版本開始,正式支援外掛系統,發揮你們的無限想象,PicGo也

Python error: Microsoft Visual C++ 9.0 is required 解決方案

compile blank 安裝ipython con pan code logs onf pre 換了新電腦,在使用python2.7 pip 安裝ipython時,報錯了 error: Microsoft Visual C++ 9.0 is required. Get

共享飛機終於!但想普及並不是短時間的事兒

共享飛機共享經濟發展的速度、廣度和深度等,都足以讓業界和大眾瞠目結舌。既有共享單車、共享出行等已經凸顯自身潛力的共享項目,也有共享籃球、共享健身倉、共享雨傘等聚焦於小眾群體的形式。而迅猛發展的共享經濟似乎也變成了奪人眼球的“噱頭”,朝著匪夷所思的方向房展。共享寶馬、共享法拉利之後,共享飛機也終於出現了!就在九

error:Microsoft Visual C++ 9.0 is required. Get it

安裝模塊報錯安裝,執行如下命令: python install virtualenv報錯如下:error: Microsoft Visual C++ 9.0 is required. Get it from http://aka.ms/vcpython27解決方法:下載 VCForPython27.msi 。

安裝paramiko報錯error: Microsoft Visual C++ 9.0 is req

aid src ref water proc mar ima c++ follow 解決方法:安裝此包VCForPython27.msi鏈接:https://pan.baidu.com/s/1Gw-o9upr28_rw9e7jdrR-w 密碼:sa62 然後再重新安裝pa

中國的to B時代終於

開始 世界 ros 分析 沒有 為什麽 軟件 def justify 一次晚宴上,GE公司CEO段小纓問IDG資本創始合夥人熊曉鴿:中國有很多偉大的公司和巨型國企,為什麽沒有出現為企業提供服務(2B)的大公司,尤其是提供軟件服務的大公司?熊曉鴿說,一方面,中國國有企業很大程

python2.7安裝第三方擴充套件庫報Microsoft Visual C++9.0 required

環境:   作業系統:Windows 7 64位   語言:Python 2.7.9   Twisted   webrtcvad 等第三方擴充套件庫 安裝,執行如下命令: pip install Twisted/...

小學AI教材終於,下一步是AI胎教嗎?

小學生終於也要學 AI 了! 據澎湃新聞報道,全國首套涵蓋了從小學到高中的人工智慧教材近日在上海正式釋出,這套“AI上未來智造者”叢書計劃出版 10 冊,目前已出版 6 冊,分別為《AI上神奇動物》、《AI上智慧生活》《AI在變形工坊》、《AI上萌寵“小E”》、《AI超

python 安裝模組時提示報錯:Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall.bat)

有時候,在Windows7x64下使用pip安裝包的時候提示報錯:Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall.bat) 環境:windows8 x64 ,python2.7 ,VS2012 解決方案:Microsoft Vi

python 安裝模塊時提示報錯:Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall.bat)

親測 解決 com pip安裝 crf 管理員 網上 pretty mic 有時候,在Windows7x64下使用pip安裝包的時候提示報錯:Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall.bat