C# 8 新增小功能

尽管C# 8应该会在今年发布,并且C# 8.x和9的路线图也开始形成,但是,微软正在继续审查下一个版本的特性。

目标类型表达式

假设我们有A、B和C三种类型,其中类型B和C是类型A的子类型。如果我们使用如下所示的语句,那么,编译器无法确定右侧要返回的类型。

A a1 = b ?? c;
A a2 = x>0 ? b : c;
A a3 = 	a switch {
    B b => b,
    C c => c,
    _ => throw new System.Exception() 
};

通常情况下,修复该问题需要添加强制转换,如:

A a1 = (A)b ?? (A)c;
A a2 = x>0 ? (A)b : (A)c;

根据目标类型switch表达式提议,在每种情况下都允许编译器使用语句(A a1)的左侧来决定右侧(b ??c)应该返回的类型。该功能还可以用于返回语句(return b ?? c),但不能用于变量(var a1 = b ?? c)。

目前,这个(例3)的模式匹配版本计划于C# 8.0中提供,其他两个则于8.x中提供。

允许在解构中使用“default”

根据该提议,这个小功能将允许在初始化元组时使用default关键字:

(int i, string s) = default;
(i, s) = default;

过时的属性

与Visual Basic不同,C#无法把单个getter和setter标记为过时。相反,只能将属性作为整体做这样的标记。该提议纠正了这种情况。为了理解这个问题的重要性,请看看Cory Nelson的评论。

就在几个星期前,我试图清理一些大量使用get/set属性的代码,使其成为一个更加只读的初始化的构造函数(ctor-initialized),此时我发现我真希望该特性是这样的。

4月,该特性从C# 9迁移到了C# 8上。

结构上的只读成员

当分配给只读字段或用作in参数时,结构上的方法有个性能小问题。如果我们调用结构上的方法,编译器首先会生成防御性副本。尽管这通常不足以产生问题,但是,在用于紧密循环(tight loop)时,细微的低效的确会累积出性能问题。

对于完全不可变的结构,可以标记整个结构为只读,这样可以避免此类情况的发生。然而,出于性能的缘故,很多结构是可变的。

根据只读示例方法提议,开发人员将能够把单个方法标记为只读。这向编译器表明,防御性副本不是必要的,没有值会被修改。

这和Pure属性不同,只要只读方法不修改结构本身的值,那么就有明显的副作用。

自动实现属性的getter将被自动认为是只读的。在某些情况下,setter也可以被标记为只读。比如,当属性值存于字典中而不是直接存入结构本身的时候。

在目前的提议下,引用类型(类和接口)将不会受到该特性的支持。原因有三重:

  • 这么做,没有与性能相关的优势
  • 只读关键字不意味着状态不会改变,只是不会直接修改对象上的字段。
  • 这是只读结构的扩展,没有等效的只读类。

查看英文原文:C# 8 More Small Features

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章