转载

微软提议在C# 7中为引用增加选项类型

微软C#语言的项目经理Mads Torgersen,最近 提议 在C# 7中引入可为 选项类型 (option types)的引用类型。加入选项类型能让C#语言变得更安全,正如Torgersen所说,在C#里,因为任一引用类型都能引用一个空值,从而导致了空引用异常的泛滥成灾,而使用选项类型能减少空引用异常的产生。

C#已经对 nullable值类型 提供了支持,即对基于struct的已提供了支持,但不支持基于class的引用类型。对一门现存的已然成熟的编程语言事后加入选项类型,这其中存在着巨大的复杂性,出于这一原因,Torgersen不打算建立一套“滴水不漏的”机制,而是在检测到代码可能存在解引用空值的时候发出警告信息。

新的提议方案对一个现有的引用类型T有如下约定:

  • T 用来表示一个非nullable类型;
  • T?用来表示一个nullable引用类型;
  • 在以下情况下,编译器将发出告警信息:
    • 一个nullable的 T?类型被解引用或者转化为一个非 nullable类型;
    • 将null/default(T)赋值给非nullable T类型变量;
    • 流分析检测到一个nullable引用很可能不再是空值;
    • 构造函数在返回前未对非nullable引用进行赋值;
    • 构造函数使用尚未赋值的非nullable引用。

另一方面,当一个非nullable数组在进行初始化时,无法确保其中为null的数组成员不被保留下来。

使用 空条件操作符 ( null-conditional operator )?.,可参考介绍C# 6,将产生以下效果:

string s; string? ns = SomeStringMaybe();  s = ns;                     // emits warning if (ns != null) { s = ns; } // ok  WriteLine(ns.Length);       // emits warning WriteLine(ns?.Length);      // ok

尽管使用这种新设计出的方法不用改动任何的现有代码,但该方法仍可能对编译器的行为产生潜在的影响,因为在当前的C#里,T实际上用来表示一个nullable类型。因此,Torgersen说,需要另外再新增一套机制来关闭告警信息,用于确保在跨C#版本和程序集下的编译兼容性。

需要重点声明的是,当所赋的值为null时,若编译器只产生告警信息,那么C# 7仍将会允许一个非nullable类型T包含null类型,这主要是出于对程序集兼容性的考虑。这也使得C# 7表现得与其他编程语言大相径庭,比如 Swift option types 和 Haskell Maybe ,在Swift和Haskell中,选项类型可被视为对基本类型的一种封装(实际上,在Swift里选项类型就是泛型类型,在Haskell里就是monad)。

从通告的评论来看,人们对微软的提议反应不一。有些人担心在重新定义了类型T为非nullable之后,现存的C#代码会产生大量的对他们来说毫无意义的告警信息。还有些人认为应该用T!或者其他不同于基本类型T的表示方式来表征非nullable类型,基本类型T继续用来表示nullable类型。微软的提议方法没有让任何已有的代码受益,应对其进行重构以使其有助于代码的non-nullability。另外有部分人支持该提议,并表示自己更喜欢这种“严谨的”模式,在这种模式下,空值经由option<T>或其它等效结构被有效地封装了起来。

查看英文原文: A Proposal to Add Option Types for References to C# 7

正文到此结束
Loading...