如何评价即将发布的 C# 9.0?

C# 9 终于也快要问世了。 Blogs: 第一部分: https://devblogs.microsoft.com/dotnet/welcome-t…
关注者
284
被浏览
200,059

42 个回答

自问自答,主要目的不在评价 C# 9.0,而在于解释一些吐槽点所在之处,以及给出改进方法和反馈渠道。

records

关于 records,目前为止官方实现的唯一写法只有:

data class(string FirstName, string LastName);
data struct(string FirstName, string LastName);

即:Positional Records,而且官方还在考虑将 data 关键字更换为 record

大会上说的那些很多只是 prototype,其他的那些比如 init 、不可变性等等目前官方还在讨论到底应该怎么写,因此那些几乎还没有开始实现,从社区的建议也不断地被采纳和参考。

如果不满意的话,建议大家尽快去 C# 语言设计仓库发 issue 提出自己的建议或问题等让官方看到,借此改进 C# 9 records 的提案,而不是在木已成舟后才后悔:

关于 records 的讨论主要在:

以及 records 是一系列特性的集合,比如 Positional Records、Nominal Records、Value-based Equality、With Experssion 等等,目前官方只 ship 了 Positional Records 和 With Expression,其他的讨论其实也有对应的 issue,如果有意见但是实在找不到对应 issue 的话可以直接发新的 issue。

and or not 模式

关于 and or not 这一点,因为 || && ! 甚至是 | & ~ 本来就具有表达式语义的,如果模式匹配沿用这些操作符就会造成二义性,考虑以下代码:

var a = foo switch
    true || false => 1,
    _ => 2

请问如果 foo false a 的值应该是什么呢?

还有:

var a = foo switch
    4 | 5 => 1,
    _ => 2

请问如果 foo 4 a 的值应该是什么呢?

因此,唯一的解决方案就是仅在模式匹配中引入新的 and or not 上下文关键字,避免歧义性。

另外,为什么这三个关键字只能用在模式匹配呢?因为这样会导致 breaking changes,使得之前用了 and or not 作为标识符的代码不能通过编译,比如下列代码:

var and = 1;
if (and == 5) { ... }

如果允许了 and or not 出现在其他非模式匹配的地方,那么上述本来能通过编译的代码将不再能通过编译,会造成很大的问题。

该特性讨论地址:

返回值协变及 Type Classes

首先,返回值协变只能用于 class 而不能用于 interface

其次,这个并不是为 Type Classes 铺路的,Type Classes 的 prototype 实现和讨论分别在下面两个链接里,并且 target 到了明年的 C# 10:

最后

C# 9 的所有候选特性都在这里,对任何特性有意见都可以去反馈,整个流程完全是透明的:

以及放一个语言特性计划板,对新特性或以后的计划有任何问题都可以直接在里面找并参与讨论:

WorkingSet 表示近期在关注中的特性,Backlog 表示有计划但是还没开始关注的特性。

最后再放一个 C# 语言设计会议记录:

所有的特性讨论和结论都完整地记录在了这里面。