一般,若是隻想用C#在控制檯上打印一行「Hello World!」,這可不是Console.WriteLine("Hello World!");一條語句就能夠搞定的,還涉及到其餘必要基礎代碼(如定義類和入口函數Main),例以下面:編程
using System; class Program { static void Main() { Console.WriteLine("Hello World!"); } }
就打印一句「Hello World!」,就這麼多代碼。這個不只對於初學者來講麻煩,並且使得代碼凌亂,而且增長了縮進層級。爲了解決這些問題,就提出了頂級代碼語句這個新特性。app
在C#9.0中,將Class的定義和主函數Main的聲明省略掉,只寫出你的核心業務代碼,就成了頂級語句。上面這段代碼,咱們能夠用頂級語句寫爲:異步
using System; Console.WriteLine("Hello World!");
這樣,代碼簡潔清晰了不少,易於初學者理解。是否是有點寫Python的感受?固然,任何語句都是容許的。若是你想返回值,你能夠那樣作;你想用await,也能夠那樣作;若是你想訪問命令行參數,args也是可用的;你想使用本地函數,也是能夠的。async
雖然可使用任何代碼,可是有一些規則要求必須遵照:編程語言
頂級語句必須放在using語句代碼後面函數
頂級語句必須用在任何類型或者命名空間聲明的前面編碼
頂級語句只能寫在一個源代碼文件裏,像現在只能寫一個main方法同樣。命令行
頂級語句中定義的本地函數和變量,在頂級代碼段外部的任何地方調用他們都會產生錯誤。code
下面這段代碼就是一個比較好的示例:對象
using static System.Console; using System.Threading.Tasks; WriteLine("Hello,"); Print(args[0]); await Task.Delay(1000); return 0; void Print(string arg) { WriteLine(arg); }
咱們知道,C#做爲面向對象的編程語言,一切類型都是面向對象的,要有類型和成員定義。頂級語句表面看着好像違反了這一規則,實際上沒有。這是由於,頂級語句最終仍是在編譯的時候,被做爲全局命空間中Program類的Main方法體中一段代碼一塊兒自動生成。以下所示:
static class Program { static async Task Main(string[] args) { // 頂級語句 } }
須要注意的是,這裏的類名Program和方法名Main只是用來舉例,其實在編譯器生成的不是這個名字。咱們能夠經過查看IL代碼確認這一點:
根據在頂級語句中是否有異步操做和返回值的狀況,生成的入口函數簽名也是不一樣的。具體以下面表格所示:
存在返回值 | 不存在返回值 | |
---|---|---|
存在異步 | async static Task<int> Main(string[] args) | async static Task Main(string[] args) |
不存在異步 | static int Main(string[] args) | static void Main(string[] args) |
例如上面代碼,生成的入口函數<Main>$就以下代碼所示:
static class Program { async static Task<int> Main(string[] args) { WriteLine("Hello"); Print(args[0]); await Task.Delay(1000); return 0; void Print(string arg) { WriteLine(arg); } } }
使用頂級語句能簡化咱們的編碼工做,使代碼看起來簡潔清晰,對初學者也很友好,本質上也未改變C#的語言的原有的語法結構,任何語句均可以使用,沒有產生額外的限制,從這些方面來講,是一個值得確定的變化。