[翻译] C# 8.0 新特性
原文: Building C# 8.0
[译注:原文主标题如此,但内容大部分为新特性介绍,所以意译标题为 "C# 8.0 新特性"]
C# 的下一个主要版本是 8.0。我们已经为它工作了很长一段时间,即使我们构建并发布了次要版本 C# 7.1, 7.2 和 7.3,我仍然对 8.0 将带来的新特性感到非常兴奋。
目前的计划是 C# 8.0 将与 .NET Core 3.0 同时发布。然而,随着我们正在开发的 Visual Studio 2019 的预览版,这些特性将开始活跃起来。当这些出来的时候,您就可以开始尝试它们,我们将提供有关各个特性的更多细节。这篇文章的目的是向您简述预期的内容,以及如何理解它们。
C# 8.0 新特性
下面是 C# 8.0 中最重要的新特性的概述。还有一些较小的改进正在进行中,这些改进将在未来几个月逐渐显现出来。
Nullable reference types 可空引用类型
此特性的目的是帮助处理无处不在的空引用异常,这种异常已经困扰了半个世纪的面向对象编程。
这个特性阻止您将 null 放入普通引用类型中(如字符串),从而使这些类型不可为 null!不过它是温和的提示警告,而不是错误。所以,它会让现有代码出现新的警告,因此您必须有选择的使用该功能 (您可以在项目、文件甚至行级别执行此操作)。
string s = null; // Warning: Assignment of null to non-nullable reference type
如果您确实想要 null 怎么办?可以使用一个可空引用类型,例如 string? 这样:
string? s = null; // Ok
当您尝试使用可空引用类型时,你首先需要检查是否为空。编译器会分析代码流,以查看 null 值是否可以将其用于当前位置:
void M(string? s) { Console.WriteLine(s.Length); // Warning: Possible null reference exception if (s != null) { Console.WriteLine(s.Length); // Ok: You won't get here if s is null } }
这个特性的要点是,C# 允许您表达“可空的意图”,并且在您不遵守它时候发出警告。
Async streams 异步流
C# 5.0 的 async/await 特性使您可以用非常简单的代码消费(或生产)异步结果, 而无需回调:
async Task<int> GetBigResultAsync() { var result = await GetResultAsync(); if (result > 20) return result; else return -1; }
如果您想要消费(或生产)连续的结果流(例如您可能从物联网设备或云服务获得),则没有那么有用。 异步流就是为此而存在的。
如果您想要消费(或生产)连续的结果流(例如您可能从物联网设备或云服务获得),则没有那么有用。 异步流就是为此而存在的。
我们现在介绍一下您所期望的 IAsyncEnumerable<T>
,即 IEnumerable<T>
的异步版本。允许您 await foreach 以消费它们的元素,并 yield return 以生产元素。
async IAsyncEnumerable<int> GetBigResultsAsync() { await foreach (var result in GetResultsAsync()) { if (result > 20) yield return result; } }
Ranges and indices 范围和索引
我们正在添加一个类型 Index,可用于索引。您可以创建一个整型来表示从头开始的索引,或者一个 ^ 前缀的从结尾表示的索引:
Index i1 = 3; // number 3 from beginning Index i2 = ^4; // number 4 from end int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; Console.WriteLine($"{a[i1]}, {a[i2]}"); // "3, 6"
我们还引入了一个 Range 类型,它由两个 Index 组成,一个用于开始,一个用于结束,并且可以用 x..y 这样的范围表达式来编写。然后,您可以使用 Range 进行索引来生成切片:
var slice = a[i1..i2]; // { 3, 4, 5 }
Default implementations of interface members 接口成员的默认实现
现在,一旦你发布了一个接口,游戏就结束了:你不能在不破坏它的所有现有实现的情况下向它添加成员。
在 C# 8.0 中,我们允许您为接口成员提供一个默认实现。因此,如果某人没有实现该成员(可能因为他们编写代码时还没有该成员),他们将只得到默认的实现。
interface ILogger { void Log(LogLevel level, string message); void Log(Exception ex) => Log(LogLevel.Error, ex.ToString()); // New overload } class ConsoleLogger : ILogger { public void Log(LogLevel level, string message) { ... } // Log(Exception) gets default implementation }
ConsoleLogger 类不必实现 ILogger 中 Log(Exception) 重载函数,因为它已经定义了默认实现。现在只要提供了一个默认实现,您就可以添加新的成员到已经存在的公开接口中了。
Recursive patterns 递归的模式匹配
在模式匹配中,现在允许模式中包含其他模式。
IEnumerable<string> GetEnrollees() { foreach (var p in People) { if (p is Student { Graduated: false, Name: string name }) yield return name; } }
这个模式 Student { Graduated: false, Name: string name }
会检查 Person 是否是 Student,然后将常量模式 false 应用于 Graduated 属性以查看它们是否已毕业,并将模式字符串 name 添加到其 Name 属性中,得到他们的名字(如果非空)。因此,如果 p 是 Student,没有毕业并且具有非空的名字,则返回该名字。
Switch expressions Switch 表达式
带有模式的 switch 语句在 C# 7.0 中非常强大,但编写起来很麻烦。switch 表达式是一个“轻量级”版本,其中所有情况都是表达式:
var area = figure switch { Line _ => 0, Rectangle r => r.Width * r.Height, Circle c => c.Radius * 2.0 * Math.PI, _ => throw new UnknownFigureException(figure) };
Target-typed new-expressions 已知目标类型的新表达式
在许多情况下,当您创建新对象时,类型已经可以从上下文中知道。在这些情况下,可以省略类型:
Point[] ps = { new (1, 4), new (3,-2), new (9, 5) }; // all Points
该功能的实现由社区成员提供,谢谢!
平台依赖性
大多数 C# 8.0 语言特性都可以在任何版本的 .NET 上运行。但是,其中一些具有平台依赖性。
Async streams, Index 和 Range 都依赖于 .NET Standard 2.1 的新类型。正如 Immo 在他的文章《公布.NET Standard 2.1》所说的那样,.NET Core 3.0 、Xamarin 、Unity 和 Mono 都将实现 .NET Standard 2.1,但 .NET Framework 4.8 不会。这意味着当您将 C# 8.0 指向到 .NET Framework 4.8 时,使用这些功能所需的类型将不可用。
与往常一样,C# 编译器对它所依赖的类型非常宽容。如果它能找到具有正确的名字和形态的类型,则很乐意将它们作为目标。
默认接口实现依赖于新的增强运行时,我们也不会在 .NET Runtime 4.8 中实现这些。因此,此特性不适用于 .NET Framework 4.8 和旧版本的 .NET。
十余年间,为了保持运行时的稳定,我们无法在其中实现新的语言特性。随着现代化运行时的并行性和开源性,我们觉得可以负责任地去重新开发它们,并在考虑到这一点时进行语言设计。 Scott 在其 .NET Core 3.0 和 .NET Framework 4.8 更新中解释说,.NET Framework 将来会看到较少的创新,而是关注稳定性和可靠性。考虑到这一点,我们认为,直接忽略某些语言特性会好一些。
想要了解更多?
C# 语言的设计过程是开源的,在这个repo中。如果您不经常跟进,可能会有点混乱和力不从心。语言设计的核心是语言设计会议,记录在 C# 语言设计日记。
大约一年前,我写了一篇介绍C#中的可空引用类型的文章。您仍然可以阅读它并得到一些信息。。
您还可以观看视频,例如 Microsoft Build 2018 大会上的 C# 未来,或者 .NET Conf 2018 大会上的即将到来的 C#,它展示了其中一些特性。
Kathleen 有一篇很好的帖子来阐述了 .Net Core 3.0 中的 Visual Basic 的计划。
当我们开始将这些功能作为 Visual Studio 2019 预览版的一部分发布时,我们还将发布有关各个功能的更多详细信息。
就个人而言,我迫不及待地要把它们交到你们所有人手中!
Happy hacking,
Mads Torgersen, Design Lead for C#
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
天猫双十一”再创新纪录背后的强大技术支撑:阿里云
2018年天猫双十一再创新纪录。2分05秒,交易额超100亿;26分03秒破100亿,1小时47分,交易额破1000亿;22小时28分,突破2000亿……阿里云创立于2009年,是全球领先的云计算及人工智能科技公司,致力于以在线公共服务的方式,提供安全、可靠的计算和数据处理能力,让计算和人工智能成为普惠科技。在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力。阿里云经过筚路蓝缕的9年创业之后,以更加开放的姿态,开始了第二次长征。这一次,剑指的是让新技术在各行业无处不在,成为转型升级的新动能。其中,还为每年的天猫双十一提供强大的数据处理支持。过去几年,阿里云收入规模连续13个季度保持接近100%增长,公司估值也从两年前的390亿美金抬升到如今的670亿美金,如果将其从阿里巴巴中单列出来,则有望成为继阿里巴巴、腾讯控股、蚂蚁金服(1500亿美金)、字节跳动(750亿美金)之后的中国第五大互联网公司。阿里云一直号称自己是全球前三的云服务商。过去几年,阿里云收入规模连续13个季度保持接近100%增长,阿里云计算的收入主要来自弹性计算,数据库,存储,网络虚...
- 下一篇
【对讲机的那点事】公网对讲机使用的物联卡你了解吗?
公网集群对讲机现在已经普及,各种公网集群对讲机的平台也渐渐进入大众视野,各种对讲平台各有各的优势,不一而足,如何选择物联卡,选择什么样的物联卡?这个是必须要关心的问题,今天小编就和你来聊聊这个话题: 既然说到选择公网对讲机平台,有一个话题肯定是绕不过去的那就是物联卡! 在对讲机行业中,做公网对讲机的经销商大部分都知道物联卡为何物,但是不少的人听说过物联网卡,不知道物联网卡是什么东西,而物联网卡这东西在很多年就开始被使用着,只不多在近两年比较火爆而已,而使用物联网卡的原理就是物物相连,通过在某种环境下,将一些对讲机进行相连,通过物联网传输数据,达到人与物、物与物之间的链接和某种需求点。 什么是物联网卡呢? 物联卡是三大运营商(移动、联通、电信)基于物联网专网,面向物联网用户提供的移动通信接入业务。采用三网专用(11位或13位)号段,通过专用网元设备支持短信、无线数据和语音等基础通信服务,提供通信链接管理和终端管理等智能通道服务。 插拔式的物联网卡 外观就是手机上使用SIM卡,这种卡根据材质分为:工业级物联网卡和普通物联网卡; 1、工业级物联网卡(移动也叫MP卡,是M2M Plug-In卡...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8编译安装MySQL8.0.19
- CentOS6,CentOS7官方镜像安装Oracle11G
- 2048小游戏-低调大师作品
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Docker快速安装Oracle11G,搭建oracle11g学习环境