原文: C# 8.0 Previewed
在一个Channel 9 的视频中,Mads Torgersen展示了C#8的首批四个新特性。
可空引用类型过去我们报道过可空引用类型,简单地说,默认情况下引用类型将不再能为空。相应的,您必须使用与可空值类型相同的 Type? 语法将其明确标记为可空。
将 null 分配给不可为空的引用类型将得到一个编译器警告。 同样,从可空类型读取也将得到一个编译器警告,除非提前对有问题的变量进行显式检查。 所以理论上开发者需要做的唯一改变是适当情况下加上问号。
自从我们的报告,这个特性添加了一个新的语法。 考虑一种情况,你明知道可空变量x实际上不是空值,但却无法编译器证明。 在这种情况下,可以使用 x!.Method() 来禁止编译器对潜在空引用异常的警告。
异步流 (即 foreach async)异步流类似于 IEnumerable 的异步方式。 正如我们之前报道的,异步流是自2015年以来一直在努力推进的事。经过多次讨论,最终确定的语法是:
foreach await (string s in asyncStream)
使用下面的方法签名来定义一个异步迭代器
async IAsyncEnumerable<T> MethodName()
与普通的 IEnumberable 方法一样,你可以使用 yield return 来懒式的构建一个对象流。
与Reactive Extensions库里的IObservable相比,这个方案的好处是消费者可以控制流量。这被称为“拉模型”,而IObservable是一种“推模型”,这意味着生产者可以向消费者提供比它所能处理的更高的流量来消耗消费者。
默认接口实现默认接口实现本质上是一种有限的多重继承形式。 这将允许抽象接口完全定义方法,就像抽象类一样。 然而,抽象接口仍然无法声明构造方法或字段。
注意:你可以使用 ConditionalWeakTable 模拟在接口上的字段。
默认接口实现的主要好处是,你可以向现有的接口添加新的方法而不破坏向后兼容性。 但是这不能保证,因为只有当一个合适的默认方法被设计出来时,它才会起作用。
这是一个非常有争议的功能。 我们不会在这里重复这些讨论,但可以在早期关于默认接口实现的文章中阅读相关总结。
扩展一切一项对C#的长期抱怨是只可以编写扩展方法,但不能扩展属性。 事实上,在当前模式下都没有办法定义扩展属性或事件。 另外,将扩展方法放在静态类中对许多人来说感觉很奇怪。
在新设计下,有一个新的顶级结构称为“扩展”。 例如,如果要为 Customer 类创建扩展方法和属性,你可以写:
extension CustomerExt extends Customer { //methods and properties go here }
与接口一样,你不能在扩展中定义实例字段,但可以使用ConditionalWeakTable来模拟它们。 你还可以定义静态字段。
除了属性,事件和操作符重载之外,甚至正在考虑允许扩展构造方法。 扩展构造方法在工厂和对象池方案中将非常有趣。
扩展接口扩展接口,将新接口添加到现有类的能力,也在考虑之中。不过这不会是一个 C# 8 的功能,因为它需要更改底层运行时。
有关C#的未来的更多信息,请查看C#语言设计仓库。