微软在 C# 8 中引入预览版可空引用类型

  • Abel Avram
  • 薛命灯

2017 年 11 月 19 日

话题:.NETC#语言 & 开发

微软已经为开发者提供了预览版的可空引用类型(Nullable Reference Type),想尝鲜的开发者可以尝试这个新特性,并提供反馈。

预览版可空引用类型是 Visual Studio 2017 15.5 Preview 4+ 的 Roslyn 扩展,现在支持.NET 框架,很快也将支持.NET Core。该特性在 C# 8 中是默认启用的。微软为此提供了安装指南

在 C# 8 中引入新的可空引用类型是为了解决十亿美元问题(Billion Dollar Mistake)。1965 年,英国计算机科学家 Tony Hoare 在开发 ALGOL 时称其为空引用(Null Reference)。指针最主要的问题是,有时候它们会为空,而这并非我们所期望的。在将空指针作为一种特性引入之后,反而变成产生 bug 的主要源头。

早在 2011 年,用户就在 Visual Studio User Voice 里要求“在 C# 中引入不可空引用类型”,一年之后,经过投票,该需求排到了第 15 位,现在已经跑到了第一的位置上。这个特性之所以在很长一段时间内都无法实现,是因为 C# 的空引用到处可见。C# 首席设计师 Mads Torgersen 解释说:

问题是空引用太有用了。在 C# 里,引用类型默认就是空值。还能用其他什么值来作为默认值吗?在你知道该给一个变量赋什么值之前,拿什么作为它的默认值?一个新创建的引用数组又该使用怎样的默认值?

有时候,空值本身也是有意义的。比如,有时候需要让一个字段不包含任何值,或者将空值作为参数进行传递也是没有问题的。但这些情况并不常见。这里还有另一个问题:像 C# 这样的语言并没有提供一种方式可以用于说明某处的空值是有意义的还是无意义的。

为了避免在 C# 中引入不可空引用类型,微软将引用类型规定为默认不可空,并提供了一些机制用于处理可空类型。他们认为,大部分情况下引用类型都是非空或被间接引用的。Torgersen 写道:

  1. 我们相信,大部分情况下引用类型都不应该为空。可空引用类型是很罕见的(尽管很难说具体多罕见),所以需要单独对它们进行注解。
  2. C# 已经提供了可空的值类型(value type)。
  3. 不应该让你自己或其他人在空值这个问题上有太多负担,除非你确定需要它们。空值应该是我们需要显式去指定的。

可空引用类型通过问号来定义,如下所示:

class Person {
  public string FirstName; // Not null
  public string? MiddleName; // May be null
  public string LastName; // Not null
}

微软希望开发者试用这个新特性,并提供反馈

更多的信息可参考 C# Futures: Nullable Reference TypesC# 8.0 PreviewedA Proposal for Non-Nullable Types in C#

查看英文原文Microsoft Previews Nullable Reference Types in C# 8

.NETC#语言 & 开发