C#7.0中新特性汇总

2019-12-30 13:57:28于丽

关于新扩展的 switch 语句,有几点需要注意:

•Case 语句的顺序现在变得重要:就像 catch 语句一样,case 语句的范围现在可以相交,第一个匹配上的会被选中。此外,就像 catch 语句一样,编译器通过去除明显不会进入的 case 来帮助你。在此之前,你甚至不需要告诉判断的顺序,所以这并不是一个使用 case 语句的巨大的改变。

•默认的语句还是最后被判断:尽管 null 的 case 语句在最后语句之前出现,它也会在默认语句被选中之前被测试。这是与现有 Switch 语义兼容的。然而,好的做法通常会将默认语句放到最后。

•Switch 不会到最后的 null 语句:这是因为当前 IS 表达式的例子具有类型匹配,不会匹配到 null。这保证了空值不会不小心被任何的类型模式匹配上的情况;你必须更明确如何处理它们(或放弃它而使用默认语句)。

通过一个 case 引入模式变量:标签仅在相应的 Switch 范围内。

元组

这是一个从方法中返回多个值的常见模式。目前可选用的选项并非是最佳的:

•输出参数:使用起来比较笨拙(即使有上述的改进),他们在使用异步方法是不起作用的。

•System.Tuple<...> 返回类型:冗余使用和请求一个元组对象的分配。

•方法的定制传输类型:对于类型,具有大量的代码开销,其目的只是暂时将一些值组合起来。

•通过动态返回类型返回匿名类型:很高的性能开销,没有静态类型检查。

在这点要做到更好,C#7.0 增加的元组类型和元组文字:


(string, string, string) LookupName(long id) // tuple return type
{
... // retrieve first, middle and last from data storage
return (first, middle, last); // tuple literal
}

这个方法可以有效地返回三个字符串,以元素的形式包含在一个元组值里。

这种方法的调用将会收到一个元组,并且可以单独地访问其中的元素:


var names = LookupName(id);
WriteLine($"found {names.Item1} {names.Item3}.");

Item1 等是元组元素的默认名称,也可以被一直使用。但他们不具有描述性,所以你可以选择添加更好的:


(string first, string middle, string last) LookupName(long id) // tuple elements have names

现在元组的接收者有多个具有描述性的名称可用:


var names = LookupName(id);
WriteLine($"found {names.first} {names.last}.");

你也可以直接在元组文字指定元素名称:


return (first: first, middle: middle, last: last); // named tuple elements in a literal

一般可以给元组类型分配一些彼此无关的名称:只要各个元素是可分配的,元组类型就可以自如地转换为其他的元组类型。也有一些限制,特别是对元组文字,即常见的和告警错误,如不慎交换元素名称的情况下,就会出现错误。