C# 9.0 中的顶级语句

Posted 全栈派

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 9.0 中的顶级语句相关的知识,希望对你有一定的参考价值。

我们创建一个最简单的C#的Hello World需要以下代码:

using System;
namespace HelloWorld{ class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); } }}


在C# 9.0中,通过使用Top-level statements(即:顶级语句,目前官方暂时是这么翻译的),你可以跳过那些繁琐的声明和不必要的流程,直接开始你的逻辑代码:


创建一个 TopLevelStatement.cs,然后写上下面代码,并运行:

System.Console.WriteLine("Hello World!");

> dotnet runHello World!


就一行代码,别的啥也没有,然后就跑起来了,并且正确执行了逻辑。我们熟悉的Main函数去哪了呢?我们使用ildasm工具来查看一下:



由上图可以看出,编译器自动生成了Main方法,并把顶级语句添加了进去。


所以,顶级语句的使用有一些使用限制。


应用程序中只能有一个文件可以使用顶级语句,如果有两个或两个以上文件使用顶级语句,则会报错:error CS8802: Only one compilation unit can have top-level statements.


如果既使用带有Main函数的应用程序入口,又同时使用顶级语句,编译器会自动使用顶级语句,而自动忽略带Main函数的应用程序入口。执行顶级语句的代码,并且会输出警告(文中使用的.NET版本参考下面输出):

> dotnet runwarning CS7022: The entry point of the program is global code; ignoring 'HelloWorld.Main()' entry point. Hello World!> dotnet --version5.0.100-rc.1.20452.10


顶级语句提供了类似脚本的编程体验,非常适合小型控制台程序和小型的助手/工具程序。不管你的应用程序多复杂,都可以使用顶层语句,顶层语句可以访问和使用任何.NET类。


顶层语句也可以接收命令行参数,也可以支持异步表达式。


传递参数,并运行。示例如下:

if (args?.Length > 0){ foreach (var arg in args) { System.Console.WriteLine(arg); }}


> dotnet run -- Hello World!HelloWorld!


异步表达式:

await System.Threading.Tasks.Task.Delay(1000);System.Console.WriteLine("Hello World!");
await System.Threading.Tasks.Task.Delay(1000);System.Console.WriteLine("Hello World!");return 10;

以上顶级语句代码生成的Main函数,分别返回TaskTask<int>

在顶级语句中使用类的时候,需要顶级语句必须得在注意类和命名空间的声明之前。譬如以下代码:

class Person{ public string Name { get; set; }}var person = new Person { Name = "Zhang San" };System.Console.WriteLine($"Hello { person.Name}!");


编译,则报如下错误:

> dotnet builderror CS8803: Top-level statements must precede namespace and type declarations.Build FAILED.


简单的调整,并运行:

var person = new Person { Name = "Zhang San" };System.Console.WriteLine($"Hello { person.Name}!");class Person{ public string Name { get; set; }}
> dotnet runHello Zhang San!


为什么类的声明要放到顶级语句之后呢?


我们继续使用ildasm来查看原因,打开编译的dll,如下图:


从上图中可以看出,编译器生成了Person类型。顶级语句的编译过程是:编译器首先获取定义的顶级语句,然后将其添加到生成的Main函数中,然后再编译该顶级语句中用到的所有类型。所以,就不难理解为什么用到的类的声明需要放在顶级语句之后了。


顶级语句又是C#的一个重大补充,是该语言的使用变得非常容易,特别是对于那种不需要额外命名空间的简单的项目。


从入门的角度来说,个人觉得对于C#初学者,使用Main函数比理解顶层语句会容易的多,因为在他们直接使用顶级语句的时候可能并不明白这后面到底发生了什么。

以上是关于C# 9.0 中的顶级语句的主要内容,如果未能解决你的问题,请参考以下文章

C# 9.0 新特性

使用 C# 9.0 新语法提升 if 语句美感

C# 9.0 中的新款匹配模式

C# 9.0 新特性预览

C# 9.0 中的新增功能

C# 9.0 中的with表达式