惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
博客园 - 司徒正美
TaoSecurity Blog
TaoSecurity Blog
Martin Fowler
Martin Fowler
T
Threat Research - Cisco Blogs
Blog — PlanetScale
Blog — PlanetScale
S
Secure Thoughts
博客园 - 三生石上(FineUI控件)
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
K
Kaspersky official blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cisco Talos Blog
Cisco Talos Blog
H
Help Net Security
博客园 - 叶小钗
爱范儿
爱范儿
GbyAI
GbyAI
I
Intezer
M
MIT News - Artificial intelligence
Latest news
Latest news
Schneier on Security
Schneier on Security
T
Tor Project blog
Simon Willison's Weblog
Simon Willison's Weblog
I
InfoQ
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
C
CXSECURITY Database RSS Feed - CXSecurity.com
罗磊的独立博客
N
News and Events Feed by Topic
T
The Blog of Author Tim Ferriss
V2EX - 技术
V2EX - 技术
B
Blog
T
Tailwind CSS Blog
N
Netflix TechBlog - Medium
Security Latest
Security Latest
V
V2EX
F
Fortinet All Blogs
Forbes - Security
Forbes - Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
The Hacker News
The Hacker News
Scott Helme
Scott Helme
P
Privacy International News Feed
P
Palo Alto Networks Blog
H
Heimdal Security Blog
C
Cisco Blogs
T
The Exploit Database - CXSecurity.com
博客园 - Franky
酷 壳 – CoolShell
酷 壳 – CoolShell
G
Google Developers Blog
W
WeLiveSecurity
L
LINUX DO - 最新话题

博客园 - Rwing

C# 13(.Net 9) 中的新特性 - 半自动属性 [翻译].NET 8 的原生AOT及高性能Web开发中的应用[附性能测试结果] C# 13(.Net 9) 中的新特性 - 扩展类型 如何在 Docker 环境下自动给 .NET 程序生成 Dump [翻译] 预览 C# 10 的新东西 [翻译]正式宣布 Visual Studio 2022 [翻译]Azure 网关迁移至 .NET Core 3.1 性能提升一倍 C# 9.0 新特性预览 - init-only 属性 C# 9.0 新特性预览 - 空参数校验 C# 9.0 新特性预览 - 类型推导的 new - Rwing [翻译] 使用 Serverless 和 .NET Core 构建飞速发展的架构 - Rwing [翻译] .NET Core 3.0 RC 1 发布 - Rwing [翻译] .NET Core 3.0 Preview 9 发布 - Rwing [翻译] .NET Core 3.0 Preview 7 发布 - Rwing [翻译] C# 8.0 接口默认实现 - Rwing [翻译] 正式宣布 .NET 5 - Rwing [翻译] ASP.NET Core 利用 Docker、ElasticSearch、Kibana 来记录日志 - Rwing [翻译] Visual Studio 2019: 极速编码. 智能工作. 创造未来. - Rwing [翻译] 使用 .NET Core 3.0 创建一个 Windows 服务 - Rwing
C# 9.0 新特性预览 - 顶级语句
Rwing · 2020-09-23 · via 博客园 - Rwing

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

前言

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

目录

[C# 9.0 新特性预览 - 类型推导的 new]
[C# 9.0 新特性预览 - 空参数校验]
[C# 9.0 新特性预览 - 顶级语句]
[C# 9.0 新特性预览 - Record 类型]
[C# 9.0 新特性预览 - 模式匹配的改善]
[C# 9.0 新特性预览 - 源代码生成器]
[C# 9.0 新特性预览 - 其他小的变化]

顶级语句 (Top-level statements)

顶级语句这个名字看起来不是那么直观,或许它的曾用名更好一些:Simple Programs,简单程序。

目的

想必大家都知道,即使是最简单的 C# 程序,也会有一定量的繁文缛节,因为最少也需要一个 Main 方法。这似乎妨碍了语言的学习和程序的清晰度。因此,这个特性的最主要目的就是为了初学者和代码的清晰度,让书写 C# 程序可以变得更轻松。

语法

语法 Spec 如下,允许在命名空间的声明前面,添加一组语句,且只允许有一个编译单元(可以认为是一个源文件)拥有这种语句:

compilation_unit
    : extern_alias_directive* using_directive* global_attributes? statement* namespace_member_declaration*
    ;

Spec 比较难懂,我们直接来看示例:简单来说,就是允许在源文件中直接书写代码语句而不用写 Main 方法:

System.Console.WriteLine("Hi!");

以上代码会被翻译为:

static class $Program
{
    static void $Main(string[] args)
    {
        System.Console.WriteLine("Hi!");
    }
}

可以看到,WriteLine语句被自动的包在了一个类和 Main 方法里面。
自动生成的 Main 方法的返回值也会根据是否异步以及是否有返回值来变化,例如:

await System.Threading.Tasks.Task.Delay(1000);
System.Console.WriteLine("Hi!");
return 0;

会被翻译为:

static class $Program
{
    static async Task<int> $Main(string[] args)
    {
        await System.Threading.Tasks.Task.Delay(1000);
        System.Console.WriteLine("Hi!");
        return 0;
    }
}

各种场景

  • 支持在 using 语句后面:
using System;

Console.Write("Hi!");

会被翻译为:

using System;

static class $Program
{
    static void $Main(string[] args)
    {
        Console.Write("Hi!");
    }
}
  • 也可以加上本地函数:
local();
void local() => System.Console.WriteLine(2);
  • 可以与其它代码共存,例如类的声明:
Type.M();
static class Type
{
    public static void M()
    {
        System.Console.WriteLine("Hi!");
    }
}

稍微复杂一点的:

await using (var x = new C())
{
    System.Console.Write("body ");
}
class C : System.IAsyncDisposable, System.IDisposable
{
    public System.Threading.Tasks.ValueTask DisposeAsync()
    {
        System.Console.Write("DisposeAsync");
        return new System.Threading.Tasks.ValueTask(System.Threading.Tasks.Task.CompletedTask);
    }
    public void Dispose()
    {
        System.Console.Write("IGNORED");
    }
}
  • 同时兼容了using alias的语法
using alias1 = Test;
string Test() => ""1"";
System.Console.WriteLine(Test());
class Test {}
delegate Test D(alias1 x);
namespace N1
{
    using alias2 = Test;
    delegate Test D(alias2 x);
}
  • 也可以同时与显示的 Main 方法声明在一起,只不过显示的Main方法会被忽略掉并提示一个警告
using System;
using System.Threading.Tasks;
System.Console.Write("Hi!");
class Program
{
    static void Main() // warning CS7022: The entry point of the program is global code; ignoring 'Program.Main()' entry point
    {
        Console.Write("hello");
    }
}

限制

  • 不支持在多个编译单元下拥有顶级语句:
// file1.cs
System.Console.WriteLine("1"); // error CS9001: Only one compilation unit can have top-level statements.

// file2.cs
System.Console.WriteLine("2"); // error CS9001: Only one compilation unit can have top-level statements.
  • 不能放在类的内部
class Test
{
    System.Console.WriteLine("Hi!"); // ERROR
}
  • 不能放在命名空间的内部
namespace Test
{
    System.Console.WriteLine("Hi!"); // ERROR
}
  • 要么所有分支都有返回值,要么都没有
System.Console.WriteLine();
if (args.Length == 0)
{
    return 10; // error CS0161: 不是所有代码分支都有返回值
}
  • 虽然可以可以与类声明一起写,但是在类中是无法调用到 Main 方法 args 入参的,因为编译时会编译为两个类
System.Console.WriteLine(args);
class Test
{
    void M()
    {
        System.Console.WriteLine(args); // ERROR
    }
}
  • 自然,你也不能用 args 来命名本地函数
args(1);
void args(int x) // ERROR
{}

参考

[Proposal: Simplified Null Argument Checking]
[Unit test: NullCheckedParameterTests.cs]
[LDM-2019-07-10.md]