1 背景与动机

通常,如果只想用C#在控制台上打印一行“Hello World!”,这可不是Console.WriteLine("Hello World!");一条语句就可以搞定的,还涉及到其他必要基础代码(如定义类和入口函数Main),例如下面:

using System;
class Program
{
static void Main()
{
Console.WriteLine("Hello World!");
}
}

就打印一句“Hello World!”,就这么多代码。这个不仅对于初学者来说麻烦,而且使得代码凌乱,并且增加了缩进层级。为了解决这些问题,就提出了顶级代码语句这个新特性。

2 顶级语句

2.1 介绍

在C#9.0中,将Class的定义和主函数Main的声明省略掉,只写出你的核心业务代码,就成了顶级语句。上面这段代码,我们可以用顶级语句写为:

using System;

Console.WriteLine("Hello World!");

这样,代码简洁清晰了很多,易于初学者理解。是不是有点写Python的感觉?当然,任何语句都是允许的。如果你想返回值,你可以那样做;你想用await,也可以那样做;如果你想访问命令行参数,args也是可用的;你想使用本地函数,也是可以的。

虽然可以使用任何代码,但是有一些规则要求必须遵守:

  • 顶级语句必须放在using语句代码后面

  • 顶级语句必须用在任何类型或者命名空间声明的前面

  • 顶级语句只能写在一个源代码文件里,像如今只能写一个main方法一样。

  • 顶级语句中定义的本地函数和变量,在顶级代码段外部的任何地方调用他们都会产生错误。

下面这段代码就是一个比较好的示例:

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);
}

2.2 原理

我们知道,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);
}
}
}

3 结束语

使用顶级语句能简化我们的编码工作,使代码看起来简洁清晰,对初学者也很友好,本质上也未改变C#的语言的原有的语法结构,任何语句都可以使用,没有产生额外的限制,从这些方面来说,是一个值得肯定的变化。

如对您有价值,请推荐,您的鼓励是我继续的动力,在此万分感谢。关注本人公众号“码客风云”,享第一时间阅读最新文章。

C#9.0新特性之四:顶级程序语句(Top-Level Programs)的更多相关文章

  1. C# 9.0 新特性预览 - 顶级语句

    C# 9.0 新特性预览 - 顶级语句 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大家展示它们 ...

  2. C# 9.0 新特性预览 - init-only 属性

    C# 9.0 新特性预览 - init-only 属性 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章 ...

  3. 浅谈Tuple之C#4.0新特性那些事儿你还记得多少?

    来源:微信公众号CodeL 今天给大家分享的内容基于前几天收到的一条留言信息,留言内容是这样的: 看了这位网友的留言相信有不少刚接触开发的童鞋们也会有同样的困惑,除了用新建类作为桥梁之外还有什么好的办 ...

  4. Java基础和JDK5.0新特性

    Java基础 JDK5.0新特性 PS: JDK:Java Development KitsJRE: Java Runtime EvironmentJRE = JVM + ClassLibary JV ...

  5. Visual Studio 2015速递(1)——C#6.0新特性怎么用

    系列文章 Visual Studio 2015速递(1)——C#6.0新特性怎么用 Visual Studio 2015速递(2)——提升效率和质量(VS2015核心竞争力) Visual Studi ...

  6. atitit.Servlet2.5 Servlet 3.0 新特性 jsp2.0 jsp2.1 jsp2.2新特性

    atitit.Servlet2.5 Servlet 3.0 新特性 jsp2.0 jsp2.1 jsp2.2新特性   1.1. Servlet和JSP规范版本对应关系:1 1.2. Servlet2 ...

  7. 背水一战 Windows 10 (1) - C# 6.0 新特性

    [源码下载] 背水一战 Windows 10 (1) - C# 6.0 新特性 作者:webabcd 介绍背水一战 Windows 10 之 C# 6.0 新特性 介绍 C# 6.0 的新特性 示例1 ...

  8. C# 7.0 新特性2: 本地方法

    本文参考Roslyn项目中的Issue:#259. 1. C# 7.0 新特性1: 基于Tuple的“多”返回值方法 2. C# 7.0 新特性2: 本地方法 3. C# 7.0 新特性3: 模式匹配 ...

  9. C# 7.0 新特性1: 基于Tuple的“多”返回值方法

    本文基于Roslyn项目中的Issue:#347 展开讨论. 1. C# 7.0 新特性1: 基于Tuple的“多”返回值方法 2. C# 7.0 新特性2: 本地方法 3. C# 7.0 新特性3: ...

随机推荐

  1. java 执行shell命令及日志收集避坑指南

    有时候我们需要调用系统命令执行一些东西,可能是为了方便,也可能是没有办法必须要调用.涉及执行系统命令的东西,则就不能做跨平台了,这和java语言的初衷是相背的. 废话不多说,java如何执行shell ...

  2. 直播软件开发关于Android、iOS中的视频采集步骤

    很多人对直播软件开发还是抱有想法的,但是在这个资本冷静的市场下,直播平台该怎么玩,在直播软件开发过程中哪些功能是必须具备的,这都是值得关注的话题.今天我们给大家分享一份详细的直播软件开发关于Andro ...

  3. Spark Shuffle机制详细源码解析

    Shuffle过程主要分为Shuffle write和Shuffle read两个阶段,2.0版本之后hash shuffle被删除,只保留sort shuffle,下面结合代码分析: 1.Shuff ...

  4. HTML 5 <input> multiple 属性

    <form action="demo_form.asp" method="get"> Select images: <input type=& ...

  5. 【转】BSON 和 JSON 的区别

    BSON与JSON的区别 BSON是由10gen开发的一个数据格式,目前主要用于MongoDB中,是MongoDB的数据存储格式.BSON基于JSON格式,选择JSON进行改造的原因主要是JSON的通 ...

  6. 【涂鸦物联网足迹】API及SDK介绍

    前序系列文章>>> [涂鸦物联网足迹]物联网主流通信方式 我们系列文章,都会围绕如何完成一款智能"隔空接吻机"的开发.希望能帮到各异地恋or异国恋的情侣们! 本文 ...

  7. waitpid()系统调用学习

    waitpid()的头文件 #include <sys/types.h>  #include <sys/wait.h> pid_t waitpid(pid_t pid,int ...

  8. shell编程之trap命令

    trap command  signal trap捕获信号(软中断),command一般是linux命令 若为' '表示发生陷阱时为空指令,'-'表示发生陷阱时采用缺省指令 signal: HUP(1 ...

  9. 年轻人不讲武德来白piao我这个老同志

    朋友们好啊,我是码农小胖哥. 今天有个同学问我在吗,我说什么事? 给我发个截图,我一看!噢,原来是帮忙搞个定时任务,还是动态的. 他说了两种选择,一种是用DelayQueue,一种是用消息队列. 他说 ...

  10. linux文本模式和文本替换功能

    linux文本有:正常模式,编辑模式,可视化模式,命令模式. 正常模式进入编辑模式下的快捷键: i  --光标当前位置输入 a --光标位置后输入(append) I --行首输入 A --行尾输入 ...