C# 7.1先睹为快(第一部分)

2017 年 6 月 08 日

自 2003 年以来,Microsoft 首次考虑对 C#使用带小数点后位数的版本。当前暂定下一个版本是 C# 7.1,其中有望包括:异步 Main 函数(Async Main)、默认表达式(Default Expression)、推导元组名(Infer Tuple Names)和使用泛型的模式匹配(Pattern-matching with Generics)等。

异步 Main 函数

最让测试异步代码的开发人员沮丧的,无疑是控制台应用当前不支持异步入口点(EntryPoint)。虽然变通方法是编写多行样板代码,但是这样的模式依赖于对方法的非正常使用,难于理解。例如:

复制代码
ublic static void Main()
{
MainAsync().GetAwaiter().GetResult();
}
private static async Task MainAsync()
{
... // 程序主代码。
}

为解决这个问题,在“异步 Main 函数建议”中,添加了如下四个新的函数签名,罗列了可能的入口点。

复制代码
static Task Main()
static Task<int> Main()
static Task Main(string[])
static Task<int> Main(string[])
</int></int>
{1}

如果代码中不存在另一个非异步 Main 函数,那么只要给出一个上述的入口点函数,编译器就会生成所需的样板代码。唯一的限制是需要向后兼容。

Microsoft 曾考虑允许“async void Main()”,但是这种做法会使编译器更复杂,并且 Microsoft 总体上并不鼓励在事件处理器之外使用“async void”。

默认值(即 Nothing)

VB 没有表示“null”的关键字,这是 C#和 VB 间的一个微妙的差别。但是 VB 有一个关键字“Nothing”。在语言技术规范中,对该关键字给出了如下说明:

Nothing 是一个特殊的常值。它没有类型,可转换为类型系统中的任意类型,也包括类型参数。在转换为某个特定类型后,它等价于该类型的默认值。

C#当前使用“default(T)”模式实现同一效果,但略为繁琐,尤其是类的名字很长时。C# 7.1 中将提供一个“默认常值”(Default Literal),其描述为:

这一类型的表达式可通过常值转换为默认值或 null 值,隐式地转换为 any 类型。

该类型向默认常值的推理与向 null 常值推理的工作机制一样,除非允许 any 类型(不只是引用类型)。

在可以使用 null 的地方,通常也可以使用默认常值。这一做法被看成是 C#建议中的一个倒退,可能因为人们通常会对两个非常类似的方法完成同一件事大皱眉头。在设计会议纪要中,就有人提出疑问:

我们是否正在挑起类型之争?

一个使用默认常值的例子如下:

复制代码
ImmutableArray<sometype> x = default;
return default;
void Method(ImmutableArray<sometype> arrayOpt = default)
var x = new[] { default, ImmutableArray.Create(y) };
const int x = default;
if (x == default)
if (x is default)
y = default as RefType // 编译器告警:总是 null。
int i = default
</sometype></sometype>

下面例子给出的是对默认常值的非法使用:

复制代码
const int? y = default;
if (default == default)
if (default is T)
var i = default
throw default

后者无疑是一个 C#设计上的奇特构件。在设计会议纪要中,给出了如下说法:

在 C#中,允许开发人员抛出 null。这会引发一个运行时错误,进而导致抛出一个 NullReferenceException 异常。因此,抛出 NullReferenceException 并非正大光明的,而是一种丑陋的模式。

完全没有理由允许抛出默认值。我们并不认为用户会感觉这是可行的,或是了解它的工作机制。

Microsoft 并未引入默认常值,而是考虑通过扩展“null”实现同一效果。因为在 VB 中“nothing”和“null”是两个不同的关键词,所以在 VB 中可以这样做。即使不使用关键字,VB 中也具有 null 的概念。因此,开发人员可以看到“NothingReferenceException”这样的异常。

在 C#中,开发人员可能常会有这样的一个疑问:“null 是否表示的是实际的空值,或是表示了可能为空值也可能不为空值的默认值?”我们认为,这是一个令人非常困惑的问题。

在本文的第二部分中,我们将介绍元组和模式匹配。

查看英文原文: An Early Look at C# 7.1: Part 1

2017 年 6 月 08 日 19:007764
用户头像

发布了 226 篇内容, 共 59.3 次阅读, 收获喜欢 14 次。

关注

评论

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

如何理解Java8 的函数式编程

Rayjun

Java 函数式编程

Requests模块基本操作

骆俊

第十章作业

武鹏

关于 Bash 的 10 个常见误解

柴锋

bash Linux DevOps Shell

如何让区块链技术能够更好赋能数字社会建设

CECBC区块链专委会

区块链 数字经济

吃灰的旧显示器别扔!

Sicolas Flamel

学习 随笔杂谈

应用开发基础之-并发编程

superman

十年一梦,小米的原罪得到救赎了吗?

脑极体

求刚好大于当前数组组合,Code Review最佳实践,JVM框架原理,JVM垃圾回收原理 John 易筋 ARTS 打卡 Week 12

John(易筋)

Code Review ARTS 打卡计划 JVM虚拟机原理 JVM垃圾回收原理 Array算法

Java 常见的几种 OOM

hepingfly

Java OOM

ARTS打卡 第11周

引花眠

ARTS 打卡计划

计算机网络基础(十六)---传输层-可靠传输的基本原理

书旅

计算机网络 网络 协议族 网络层

深化区块链技术的应用 体现其价值产业发展良机

CECBC区块链专委会

区块链技术 数字经济

那些不可貌相的代码规范

双儿么么哒

代码质量

微服务、DDD

chenzt

程序的机器级表示-控制

引花眠

计算机基础

面试这么撩准拿offer,HashMap深度学习,扰动函数、负载因子、扩容拆分,原理和实践验证,让懂了就是真的懂!

小傅哥

Java 面试 hashmap 负载因子 扰动函数

十多位全球技术专家,为你献上近十个小时的.Net微服务介绍

newbe36524

微服务 .net core netcore 容器化

学了那么多技术,为何依然成不了架构师

菜根老谭

架构设计原则

Suricata-流的处理

Phantasm

网络安全 suricata flow

BGP、OSPF、MPLS路由协议RFC分享

Phantasm

ARTS 打卡(20.07.20-20.07.26)

小王同学

ARTS-WEEK10

一周思进

ARTS 打卡计划

ARTS Week11

时之虫

ARTS 打卡计划

视读——沟通的艺术,看入人里,看出人外(第二章)

双儿么么哒

读书笔记 视觉笔记

热潮-区块链的价值能够体现在哪些方面?

CECBC区块链专委会

区块链技术 标准化 应用价值

当实证资产定价遇上机器学习

分析101

人工智能 学习 金融科技 金融 资产定价

设计模式之——JDK动态代理的源码分析

诸葛小猿

动态代理 cglib 代理模式 Proxy

LeetCode题解:21. 合并两个有序链表,迭代,JavaScript,详细注释

Lee Chen

LeetCode 前端进阶训练营

图文讲解 AQS ,一起看看 AQS 的源码……(图文较长)

程序员小航

AQS jdk源码 源码阅读 java 并发

ARTS打卡Week 10

teoking

C# 7.1先睹为快(第一部分)-InfoQ