写点什么

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

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

关注

评论

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

全网72万浏览量!阿里重磅开放 “SpringCloudAlibaba学习笔记”(附下载)!

Java 编程 架构 面试 微服务

图解 Redis丨这就是 RDB 快照,能记录实际数据的

华为云开发者联盟

redis 数据 日志 aof RDB 快照

智慧社区平台解决方案,平安小区建设解决方案

eKuiper 与百度智能边缘框架 BIE 集成方案

EMQ映云科技

边缘计算 边缘技术 边缘流式数据 #百度# 智能IoT边缘服务

一妹子揭露美团面试中一些不愉快的事情(Java岗)

Java架构师迁哥

Flutter 改善套娃地狱问题(仿喜马拉雅PC页面举例)

小呆呆666

flutter android 大前端 iOS Developer

架构之:微服务架构漫谈

程序那些事

架构 微服务 程序那些事

【案例】消除隐患,基于电力大数据的群租房智能分析

星环科技

您的出门“最后三公里”问题解决啦!

亚马逊云科技 (Amazon Web Services)

【视频】51CTO专访博睿数据COO吴静涛,解读IT运维“新范式”

博睿数据

国足晋级12强!看人工智能如何更好地预测世界级赛事!

亚马逊云科技 (Amazon Web Services)

Flutter GetX使用---简洁的魅力!

小呆呆666

flutter android 大前端 iOS Developer

未来,让我们一起想象 — “Imagine” 阿里云视频云全景创新峰会

阿里云CloudImagine

阿里云 计算机视觉 音视频 视频 英特尔

为你的身份证“加盾”,鉴伪更精准,传输更安全

百度大脑

人工智能 数据安全 身份证

昆明智慧安防小区建设方案,平安社区建设

一种更优雅的Flutter Dialog解决方案

小呆呆666

flutter android 大前端 iOS Developer

阿里专家把SpringBoot:入门+基础+进阶+项目全部整理出来了

Java 编程 架构 面试 微服务

查漏补缺!复盘B站面试坑我最深的Java并发:JDK源码剖析

Java 编程 程序员 架构 面试

权限与认证:HTTP状态码返回

程序员架构进阶

Java HTTP 28天写作 6月日更

秋招冲刺:网络安全工程师入围成功之旅!!

网络安全学海

面试 运维 网络安全 信息安全 渗透

今天,「浪潮云说」直播间开讲啦!

java特点了解及JDK初谈(程序员必看!)

Java 程序员 面试

备战金九银十:4000道Java面试真题合集,助你搞定面试官

花168大洋买来的【阿里P8Java成长笔记】,看完才知道我就是菜鸡

Java架构师迁哥

千古无同局?围棋在线教育还有这样的打开方式!

亚马逊云科技 (Amazon Web Services)

密码合规测评新服务:“微咨询”正式发布

腾讯安全云鼎实验室

密码合规 微咨询

为什么要学习JVM,仅为面试?又该如何学习?

Java架构师迁哥

【源码篇】ThreadLocal的奇思妙想(万字图文)

小呆呆666

Java 源码 架构 源码分析 设计

科技前沿:一张图数字孪生北京大兴国际机

一只数据鲸鱼

数据可视化 智慧城市 指挥交通 智慧航空

Nginx的进程管理与重载原理

Linux服务器开发

nginx 后端 中间件 Linux服务器开发 进程管理

【源码篇】Handler那些事(万字图文)

小呆呆666

Java android 源码 Android Studio Android进阶

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