写点什么

C# 9: 迈向支持脚本编程的第一步

2020 年 6 月 11 日

C# 9: 迈向支持脚本编程的第一步

不需要任何样板代码是脚本语言的一个显著特征,你可以直接在文件的第一行编写声明和语句,就像在函数内部一样。相反,诸如 VB,C#或者 Java 之类的非脚本语言,在类文件中就必须包含类似“main”方法的样板代码。


微软的 C#开发经理Mads Torgersen3117提案中建议 C# 9 支持顶层语句和函数的功能。该提案允许在文件中直接编写语句和函数,而无需使用类(Class)进行包装。Torgersen 声称该提案的初衷是:


C#编译器目前支持一种可用于各种脚本开发和交互目的的语言方言,使用该方言,可以直接在顶层编写语句和非虚成员,而不需要使用成员体或类型进行包装。

虽然脚本方言很少被使用,且在某些方面上,它还没有跟上“主流”的 C #语言,但是通过 Try.NET 和其他技术的使用场景却在快速增加,因此我担心 C#未来会出现两种不兼容的脚本方言。


虽然当前版本的 C#脚本还没有被广泛使用,但 Torgersen 预测未来这个局面会被打破:


除了 Try.NET 之外,C#脚本在数据科学和机器学习的使用场景也在增加,而且使用者可以直接从实时数据交互这种模式中受益。

那么为什么不将交互 / C#脚本分开呢?因为我认为使代码能够在“实验”和“软件研发”之间来回切换是非常有价值的。


Torgersen 认为以下三种方案,都可以实现顶层语句/函数的功能:


方案 1

如果采纳该方案,那么执行语言将被允许出现在命名空间声明之前。这些执行语句将被编译到一个主函数内,然后该主函数会被放到一个程序(Program)类中,该主函数可支持异步操作。


如果多个文件都在命名空间的外部声明了执行语句,那么编译器会报错,除非你希望拥有多个包含主函数的程序类。


译者注:

方案 1 中,顶层语句最终会被编译成如下代码:

static class Program

{

static async Task Main(string[] args)

{

// 这里是你定义在命名空间外部的语句

}

}


方案 2

方案 2 是实现顶层函数,该方案允许在命名空间内或者全局定义函数,尽管公开函数也是允许的,但这些函数将被默认当作内部函数。从调用者角度来看,这些函数将直接属于该命名空间(这也是 VB 模块中函数的工作原理)。


方案 2 可能的实现思路是,生成一个局部类,将这些成员包装成静态成员。这个局部类的名称不是特定某个名字,可能是在确保不同程序集的相同命名空间中,通过某种方式生成的不重复的名称。只要顶层成员中有一个是公共的,那么这个局部类就是公共的,通过这种方式,可以让程序集知道那些成员是可以直接对外暴露的。


方案 3

虽然现有的 C#脚本方言和 C#本身是 2 种不同的语言,但方案 3 目的不是消除脚本方言,而是为了让这 2 种语言结合的更加紧密。Torgersen 说到:


如果在 C#中添加对顶层语句和函数的支持,那么我们不希望顶层语句和函数的执行和其在脚本中执行有冲突。相反,在保持语义功能一致的前提下,我们希望在必要的时候,以某种方式对它们进行必要的编译。这并不会完全消除脚本语言,因为我们仍然需要处理它们所依赖的特殊指令和“魔法命令”。但至少我们可以避免相同的语法表达不同的逻辑。


目前,Mads 建议 C#只关注方案 1,他说到:


你可以大胆的想象下,要实现一个满足所有方案功能,将会是怎样。那将需要进行大量的设计,考虑大量的细节,因此我不建议这样做,相反,我认为我们应该关注在方案 1 的实现上。因为本质上,方案 1 其实已经基本包含了其他方案。


同时他提到,在使用方案 1 实现任何功能的时候,将来都不会给实现方案 2 和方案 3 带来困扰。


设计细则

顶层语句的第一条规则是,项目中只允许一个文件存在顶层语句。就像只能有一个“Main”函数一样,如果在一个文件中包含多个 naked 语句,那么编译器会报错。


语句的内容决定了最终编译产生的代码形式。无论语句是否使用了 await 关键字或者是否有 return 表达式(例如:return 5),编译输出的代码形式只会是以下四种:


static void Main(string[] args)static int Main(string[] args)static Task Main(string[] args)static Task<int> Main(string[] args)
复制代码


支持相同的语法,就像普通方法中使用本地函数一样。


原文链接:


C# 9: Towards First Class Support for Scripting


2020 年 6 月 11 日 09:382110

评论

发布
暂无评论
发现更多内容

食堂就餐卡系统设计 - 简陋版

X﹏X

week01作业

seki

架构师训练营-Week1-作业2

车小勺的男神

第1周 学习总结

安阳

架构师第一周上课总结

种个大西瓜

【总结】架构师如何做架构

小胖子

【第一周】学习总结

黑莓

使用VSCode连接到IBM Cloud区块链网络

程序那些事

智能合约 hyperledger fabric ibm cloud

架构师训练营——第一周总结

Andy风

小师妹学JavaIO之:NIO中Channel的妙用

程序那些事

io nio 小师妹 buffer channel

量子技术到底有哪些突破值得重点关注?

蔡芳芳

第一周:架构方法-架构师如何做架构学习总结

DZ

《第一章:架构师如何做架构》总结

尔东雨田

极客大学架构师训练营

【第一周作业】食堂就餐卡系统设计

黑莓

架构师训练营--第1周总结感想

芥菜

SpringBoot分布式任务中间件开发 附视频讲解 (手把手教你开发和使用中间件)

小傅哥

小傅哥 中间件 springboot 分布式任务

Week 01 食堂饭卡系统设计

Geek_165f3d

玄姐公开课总结【构建基于ServiceMesh的普适业务中台架构】

魔曦

架构 Service Mesh

就餐卡系统设计

小胖子

架构方法

shangyu

极客大学架构师训练营

架构师训练营-Week1-作业1

车小勺的男神

食堂就餐卡设计说明书

架构师训练营——第一周总结

养乐多

week01总结

seki

极客大学架构师训练营

食堂就餐卡系统设计文档

秤须苑

极客大学架构师训练营

架构师训练营作业一:食堂就餐卡系统设计

常江舟

极客大学架构师训练营

架构师训练营第一周学习总结

常江舟

极客大学架构师训练营

架构师课程学习第一周心得

秤须苑

极客大学架构师训练营

架构方法:架构师如何做架构

让独立思考成为习惯

Neco.W

学习 深度思考 思考

02-kubernetes自建CA及双向TLS认证

绿星雪碧

Kubernetes TLS CA证书

2021年全国大学生计算机系统能力大赛操作系统设计赛 技术报告会

2021年全国大学生计算机系统能力大赛操作系统设计赛 技术报告会

C# 9: 迈向支持脚本编程的第一步-InfoQ