写点什么

C# 7.3 新特性一览

  • 2018-05-23
  • 本文字数:2272 字

    阅读完需:约 7 分钟

看新闻很累?看技术新闻更累?试试下载 InfoQ 手机客户端,每天上下班路上听新闻,有趣还有料!

通过一个相对较小的版本,C# 7.3 解决了一些自 C# 1 和 2 以来长期悬而未决的问题。

重载解析

从 C# 1.0 开始,重载解析规则的设计就相当有问题。在某些情况下,它会选两个或更多方法作为候选,虽然所有这些方法中只有一个会被使用。根据这些错误选出的方法的优先级,编辑器要么会报没有匹配的方法,要么会报匹配不明确。

C# 7.3 把其中部分检查移到了重载解析期间,而不是重载解析之后,这样,错误的匹配就不会导致编译器错误。改进后的重载候选提案概括了这些检查:

  1. 当一个方法组既包含实例又包含静态成员时,如果调用时没有实例接收者或上下文,我们就会丢弃实例成员,如果调用时有实例接收者,我们就丢弃静态成员。当没有接收者时,我们只会在一个静态上下文中包含静态成员,否则会同时包含静态和实例成员。当不确定接收者是实例还是类型时,考虑到 color-color 的情况,我们会两者都包含。在静态上下文中,不能使用隐式的 this 实例接收者,它包含的方法体中没有定义 this,如静态成员,它还包含不能使用 this 的地方,如字段初始化器和构造函数初始化器。
  2. 当方法组包含一些泛型方法,而它们的类型参数不满足约束时,这些成员会被从候选集中移除。
  3. 对于方法组转换,那些返回类型与委托的返回类型不一致的候选方法会被从候选集中移除。

泛型约束:枚举、委托和非托管

自 C# 2.0 引入泛型以来,开发人员就一直在抱怨,无法把一个泛型类型指定为枚举。这个问题终于解决了,你现在可以使用 enum 关键字作为泛型约束了。同样,你现在可以使用 delegate 关键字作为泛型约束了。

这些关键字可能并不是和你预期的那样发挥作用。如果约束是 T : enum,那么有人可能就会使用 Foo,而你的意思也许是让他们使用 System.Enum 的子类。尽管如此,这应该可以覆盖枚举和委托的大多数使用场景。

非托管类型约束提案使用了 unmanaged 关键字,用于说明泛型类型必须是“非引用类型,并且在任意嵌套层次上都不包含引用类型字段。”这是为了用在底层交互代码中,当你需要“创建可供所有非托管类型重用的例程时”。非托管类型包括:

  • 基元类型 sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal、bool、IntPtr 或 UIntPtr;
  • 任何枚举类型;
  • 指针类型
  • 只包含上述类型的用户定义结构。

隐藏字段的 Attribute

虽然自实现的 Property 非常有用,但是它们有一些局限,Attribute 不适用于后备字段,因为你看不到它。虽然通常来说这不是问题,但在处理序列化时就可能有问题了。

面向自实现Property 字段的Attribute 提案用一种简单的方法解决了这个问题。当把一个Attribute 应用到一个自实现的Property 时,只需在字段定义时加上field: 修饰符。

复制代码
[Serializable]
public class Foo {
[field: NonSerialized]
public string MySecret { get; set; }
}

元组比较(== 和!=)

虽然提案的名称“支持元组类型 == 和!= 比较”很好地概括了这项特性,但还有一些细节和边际情况需要注意。最重要的是潜在的破坏性变化:

如果有人自己编写了一个 ValueTuple 类型,并实现了比较操作符,之前,重载解析会找到它们。但是,新的元组情况出现在重载解析之前,我们会通过元组比较处理这种情况,而不是基于用户定义的比较。

理想情况下, 这个自定义的 ValueTuple 类型会遵循与 C# 7.3 编译器同样的规则,但是,在如何处理嵌套元组和动态类型方面,可能会有微妙的差别。

初始化器中的表达式变量

在某种程度上,这看上去像个反特性。微软不仅没有增加功能,而是去掉了表达式变量的使用场景限制。

我们移除了在 ctor 初始化器中不能声明表达式变量(out 变量声明和声明方式)的限制。这样声明的变量其作用域是整个构造函数的函数体。

我们移除了在字段或 Property 初始化器中不能声明表达式变量(out 变量声明和声明方式)的限制。这样声明的变量其作用域是整个初始化表达式。

我们移除了在会被翻译成 lambda 表达式主体的查询表达式子句中不能声明表达式变量(out 变量声明和声明方式)的限制。这样声明的变量其作用域是整个查询子句表达式。

最初增加这些限制只是因为“没有时间”。也许,这些限制缩短了了 C# 7 之前版本完工所需的测试时间。

栈分配数组

C#中有一个很少使用单相当重要的特性,就是能够通过 stackalloc 关键字在栈上分配数组。与分配在堆上、会导致 GC 压力的普通数组相比,这可能会提供更好的性能。

复制代码
int* block = stackalloc int[3] { 1, 2, 3 };

使用栈分配数组有点危险。因为它需要持有一个指向栈的指针,而且只能用于不安全的上下文中。CLR 会启用缓冲区溢出检测来缓解这种情况,那会导致“应用程序尽快终止”。

在 C# 7.3 中,你可以在创建数组时对其初始化,就像你对普通数组所做的那样。该提案没有提供细节,但微软正考虑预初始化一个主数组,当函数被调用时可以快速复制。理论上讲,这比创建一个数组然后一个元素一个元素的初始化要快。

注意,栈分配数组适用于需要大量小数组供短暂使用的场景。不能把它用于大数组或者深度递归函数,因为那可能会超出可用的栈空间。

栈分配Span

栈分配数组的一个安全替代方案是栈分配Span。消除指针,也就消除了缓冲区溢出的可能性。反过来,这意味着你可以使用它而不必把方法标记为不安全的。

复制代码
Span<int> block = stackalloc int[3] { 1, 2, 3 };

注意,Span 依赖于 NuGet 包 System.Memory。

可重新赋值的 Ref 局部变量

Ref 局部变量现在可以和普通局部变量一样重新赋值了。

要了解其他C# 7.3 提案,请查阅C#语言的GitHub 站点。

查看英文原文 New Features in C# 7.3

2018-05-23 15:174377
用户头像

发布了 1008 篇内容, 共 388.0 次阅读, 收获喜欢 344 次。

关注

评论

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

大模型走向产业的一小步,AI走向普惠的一大步

脑极体

druid 源码阅读(十一)maxWait 参数

爱晒太阳的大白

5月月更

Kitex 源码解析活动发布!

baiyutang

Go 字节跳动 微服务 5月月更

Tech Talk 活动回顾|化“被动”为“主动”,如何构建安全合规的智能产品

亚马逊云科技 (Amazon Web Services)

产品 安全 解决方案

Amazon Personalize 个性化效果评估,从准确性到多样性、新颖性和偶然性

亚马逊云科技 (Amazon Web Services)

Amazon 模型

单片机上常用-GB2312、GBK汉字取模与字库偏移地址的计算与汉字描点

DS小龙哥

5月月更

Vite 与 Vue Cli 对比 - 尤雨溪: Vite 会取代 vue-cli 吗?

蒋川

Vue vite vue cli

零基础学Java第四节(字符串相关类)

编程攻略

java编程

【中国信通院 x ShardingSphere 金融用户社区】成立,多家知名金融机构正式入驻

SphereEx

Apache 数据库 开源 ShardingSphere SphereEx

Druid 连接池源码阅读 10

石小天

Amazon MSK Serverless 现已正式推出,无需再为托管式 Kafka 集群进行容量规划

亚马逊云科技 (Amazon Web Services)

kafka Serverless

Kubectl-ice 插件展示集群容器配置信息更强大、更便捷

Marionxue

kubectl插件 kubectl-ice 容器配置

使用 Provider 实现 Flutter 多组件的状态共享

岛上码农

flutter 安卓开发 ios 开发 跨平台应用 5月月更

druid 源码阅读 10—— 过一下流程图中的getConnectionDirect

张大彪

设计者模式之装饰者模式

乌龟哥哥

5月月更

区块链技术已站上真正意义的风口,如何把握?

CECBC

【LeetCode】在长度 2N 的数组中找出重复 N 次的元素Java题解

Albert

LeetCode 5月月更

【Meetup 预告】OpenMLDB x DolphinScheduler 链接特征工程与调度环节,打造端到端 MLOps 工作流

第四范式开发者社区

人工智能 机器学习 数据库 调度 特征工程

模块六:作业

本人法海

「架构实战营」

JSON在线对比差异工具

入门小站

工具

css基本概念学习篇【四】

恒山其若陋兮

5月月更

如何在你的 wordpress 网站中添加搜索框?

海拥(haiyong.site)

WordPress 5月月更

百尺竿头更进一步丨拓展 Amazon Aurora 的读写能力之 Gaea 篇

亚马逊云科技 (Amazon Web Services)

Amazon 环境搭建

在线HTML转TSV工具

入门小站

工具

代码之外:校招该如何准备开发项目

宇宙之一粟

校招 项目开发 5月月更

深入剖析 | snowflake算法

九叔(高翔龙)

算法 雪花算法 uuid 全局唯一ID snowflake

druid源码学习十

Nick

Apache Druid

数据结构之时间复杂度和空间复杂度

芒果酱

数据结构 算法 5月月更

Docker下Java文件上传服务三部曲之三

程序员欣宸

Java Docker 5月月更

SAP UI5 OData V4 模型的构造方式

汪子熙

JavaScript 前端 SAP ui5 5月月更

【刷题第15天】剑指 Offer 09. 用两个栈实现队列

白日梦

5月月更

C# 7.3新特性一览_.NET_Jonathan Allen_InfoQ精选文章