写点什么

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:175340
用户头像

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

关注

评论

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

《MyCat数据库的基础配置及使用》

java小李

java 14 mycat

技术解码 | GB28181协议简介及实践

腾讯云音视频

腾讯云 ffmpeg 流媒体 视频监控系统

MySQL高频面试题的灵魂拷问

java小李

MySQL

当面试官问到:《MySQL数据库的锁机制》该如何拿分?

java小李

spring Boot Starter

一条SQL语句执行得很慢的原因盘点

北游学Java

Java MySQL

解决方案| 全民抗“灾”- 实时音视频在应急指挥场景的应用

anyRTC开发者

音视频 WebRTC 指挥调度

如何借用第三方APM工具, 为移动应用保驾护航

APM

Git提交信息规范化

admin

git flow git cherry-pick Git Commit git 规范

四面字节跳动,终于拿下1-2级offer :Redis+分布式+微服务+算法+网络

Java 程序员 架构 面试 计算机

这款开源软件绝了!1分钟即可打造了一个”黑客范“终端~

编程菌

Java 编程 程序员 项目 计算机

编辑器看看

strive

编辑器

使用Docker在无网络环境下搭建深度学习环境

左晖:凭一己之力改变了一个行业

石云升

思维模型 诚信 7月日更

幸福的人在当下就活出了幸福的样子|靠谱点评

无量靠谱

最新流行的6大优秀DevOps工具

java小李

java 14 puppeteer

他是因为什么,能在半年内从菜鸟学生成为大厂收割机?

Java架构师迁哥

降低“美丽成本”,区块链助力化妆品行业数字化转型

旺链科技

区块链 数字化转型 化妆品行业

架构训练营模块3课后作业-学生管理系统详设文档

喻高咏        

iOS底层面试题(下篇)

程序员 面试 ios开发

详解TCP协议与UDP协议的区别

Linux服务器开发

网络协议 Linux服务器开发 Linux后台开发 TCP协议 UDP协议

“普通本科Java程序员,如何五年存够80万买房?就靠这选择!”

java小李

java 14

GitHub标星139K的:“嵌入式Linux系统开发教程”

白亦杨

基于 Java Spring Security 的关注微信公众号即登录的设计与实现ya

哈德韦

spring security 微信公众号 Apache Pulsar SSO

万万没想到,阿里巴巴被挂后,还能获得内推名额,五面口碑一举拿下offer

Java 编程 程序员 架构 面试

深度融合,云管理平台助推政府实现“最多跑一次”改革

BoCloud博云

云计算 云管理平台 云管理

ipfs矿机最新消息?星际联盟矿机怎么样?

区块链 fil ipfs矿机 星际联盟

《分享几道高频 Redis 高频面试题,面试不用愁》

java小李

Redis Stream

数字化成潮流,运维为啥也热了?

ToB行业头条

科技互联网

FBI 警告称,网络犯罪分子可能以 2021 年东京奥运会为目标!

郑州埃文科技

被转载10W次的:Java小白系统资料和职业规划路线

java小李

java基础

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