C# 7.0新功能

下面是对C#7.0 版本所有语言功能的描述。随着 Visual Studio “15” preview 4 的发布,大部分功能可以被更灵活的应用。现在正是时候将这些功能介绍给大家,你也可以借此让我们知道你的想法。

  C#7.0 增加了很多新的功能,更专注于数据的消费,代码的简化及代码的性能。或许最大的功能就是元组和模式匹配,它可以快速获得多个返回结果,而模式匹配,它可以根据数据的“形”的不同来简化代码。我们希望将它们结合起来,从而使你的代码更加简洁高效,也可以使你更加快乐并富有成效。您可以点击 Visual studio 窗口顶部的“send feedback”按钮来告诉我们是否有哪些功能没有达到预期的功效,也可以告诉我们您对功能进一步改善的一些看法。还有许多功能没有在 Preview 4 中实现。我们计划在最终版本发布下面所描述的功能,如果我们不能及时发布这些功能,会在 notes 上通知大家的。如果这些功能有变化,我们也会通知大家的。最终可能会有一些功能的改变和删除。

  如果你对这些功能的设计过程感兴趣,你可以在 Roslyn GitHub site 上查看我们的设计笔记和讨论。

  希望你对C#7.0 有一个愉快的体验。

  输出变量:

  在当前的 C# 版本,使用 out 参数可能不像我们想的那样方便。在你调用一个带有 out 参数的方法之前,你必须首先声明一个变量并传递给它。你通常不会初始化这些变量(毕竟它们会被方法重写),也不能用 var 去声明他们,而是必须指定数据的完整类型。

  在C#7.0 版本中,我们添加了 out 变量,可以在给一个函数传入参数的时候再去定义变量的能力。

  变量的作用域是一个封闭的块,因此后续的代码行也可以使用它们。大多数类型的语句都没有它们自己的作用域,因此被声明的 out 参数通常被引入到封闭的范围内。

  注:在 Preview 4 中,适用范围规则有了更多的限制:out 参数的作用域是声明它的语句。因此,上面那个例子只有在下一次发布的时候才能真正使用。

  因为 out 变量会直接被当做 out 参数来声明,这样编译器通常会告诉他们应该是的类型(除非它们被重载),所以我们可以用 VAR 来定义,而不必使用真正的类型。

  Out 参数的一种常见用法是 Try…模式, 其中一个布尔返回值表示成功,out 参数会携带所获得的结果:

  注:这里的i仅仅在 if 分支中会用到,所以 Preview 4 可以很好的处理这种情况。

  我们还可以使用通配作为 out 参数,用*的形式来处理,这样你就可以不必关注你不想关注的返回值了。

  注:我们还不确定在C# 7.0 是否可以使用通配符。

  模式匹配

  C# 7.0 引入了模式的概念,抽象的讲,模式是语法元素,能用来测试一个数据是否具有某种“形”,并且在它被使用的时候从中提取信息。

  C# 7.0 中的模式示例:

  • C形式的常量模式(C是 C# 中的常量表达式),我们可以验证输入是否等于C

  • TX 形式的类型模式(T是一种类型,X 是一个标识符)。

  • Var x 形式的 Var 模式 (x是一个标识符)。

  这仅仅是一个开始,模式是 C# 中的一个新语言元素,我们希望未来在 C# 中会有更多类型的模式。

  在C# 7.0 中,我们改进了两种已经存在的模式语法设计:

  • is 表达式的右值也可以是模式,而不仅仅只能是一种类型。

  • switch 中的 case 分支,也可以匹配模式,而不仅仅是常量了。

  在未来,我们会增加更多模式的使用。

  使用模式 IS 的表达式

  下面是一个使用 Is 表达式的例子,用到了常量模式和类型模式。

  正如你所看到的,模式变量(模式引入的变量)很像之前说过的输出变量,可以在表达式中声明,并且在最近的定义域中使用。就像输出变量一样,模式变量是可变的。

  注:像输出变量(out variables)一样,我们会在 Preview 4 给出更加严谨的规则。

  模式和 Try 方法一起用也是可以的。

  带模式的 Switch 语句

  我们正在归纳总结这些 switch 语句,因此:

  • 你可以在任何类型上使用 switch(不仅仅是原始类型)

  • 可以在 case 子句中使用模式

  • Case 子句可以拥有额外的条件

  下面是一个例子

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

  • Case 子句的顺序现在很重要:就像 catch 子句,case 子句不再是必然不相交的,第一个子句匹配的将被选择。

  • 默认子句总是最后被判断:即使上面代码中 null 子句是最后才来,它会在默认子句被选择前被检查。这是为了与现有 switch 语义相兼容。然而,好的做法通常会让你把默认子句放到最后。

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

  元组

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

  输出参数。使用笨拙(即便有上面描述到的改进),它们在使用异步方法时不起作用。

  • System.Tuple<…>返回类型。使用繁琐并且需要分配一个元组对象。

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

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

  为了在这方面做得更好,C# 7.0 添加了元组类型和元组文字:

  这个方法可以有效地返回三个字符串,将其作为元素包含在一个元组值里。

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

  Item1 等是元组元素的默认名,并能够一直使用。但它们不具有描述性,因此你可以选择添加更好的。

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

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

  通常来说,你可以给元组类型分配相互无关的名字,只要独立的元素是可以被分配的,元组类型会自如转换成其他元组类型。但是也存在一些限制,特别是对于元组文字,会在常见的错误情况下警告或提示,例如偶然交换元素的名字。

  注:这些限制还没在 Preview 4 中实现 。

  元组是值类型,而且他们的元素是公开的、可变的。两个元组相等(并且有相同的哈希值),意味着它们的元素都是成对匹配的(并且有相同的哈希值)。

  这使得元组对于在需要多个返回值的情况下非常有用。举例来说,如果你需要一个有多种键的词典,使用元组作为你的键,一切会非常顺利。如果你需要在每个位置有多种值的列表,使用元组进行列表搜索,程序会正常运行。

  注:元组依赖于一组基本类型,它们还没包括在 Preview 4 中。为了使该特性工作,你可以通过 NuGget 获取它们:

  • 在 Solution Explorer 中右键点击项目,并选择“管理 NuGet 包…”

  • 选择“Browse”选项卡,选中“Include prerelease” ,选择“nuget.org”作为“Package source”

  • 搜索“System.ValueTuple”并安装它

  Deconstruction 解构

  消耗元组的另一种方法是解构元组。解构声明是一种将元组拆分,并单独分配到新变量的语法:

  在解构中可采用 var 关键字来声明单独的变量:

  或者把 var 关键字提取出来放在括号外:

  你也可以通过解构赋值来解构成一个现有变量:

  解构不仅仅适用于元组。任何类型都可以被解构,只要它有一个对应的(实例或扩展)解构方法:

  输出参数由结构产生的值构成。
(为何它使用了参数,而不是返回一个元组?这是为了让你可以针对不同的值拥有多个重载)。

  构造函数和解构函数以对称方式出现是一种常见的模式。
至于输出变量,我们计划在解构中使用“通配符”,来化简你不关心的那些变量:

  注:现在仍然不能确定通配符是否会出现在C#7.0 中。

  局部函数

  有时,一个辅助函数只在一个使用它的单一方法的内部有意义。现在你可以在其他功能体内部以一个局部函数来声明这样的函数:

  闭合范围内的参数和局部变量在局部函数内是可用的,就像他们在 lambda 表达式中一样。
举个例子,迭代的方法实现通常需要一个非迭代的封装方法,以便在调用时检查实参。(迭代器本身不能启动,直到调用 MoveNext 才会运行)。局部函数非常适合这样的场景:

  如果 Iterator 是紧随 Filter 的一个私有方法,它将有可能被其他成员不小心使用(不需要参数检查)。此外,它将采取所有跟 Filter 里相同的参数,而不是指定域内的参数。

  注:在 Preview 4 版本中,局部函数必须在它们被调用之前声明。这个限制将被放松,能调用读取直接赋值的局部变量。

  文字改进

  C#7.0 允许用”_”作为数字分隔符:

  你可以把它们放在任意的数字之间,以提高可读性。这对数值没有影响。
另外,C # 7 引进了二进制数,因此,您可以直接指定二进制模式,而不需要知道十六进制符号。

  引用返回和局部引用

  就像在C#中你可以通过引用(用 ref 修饰符)传递参数,你现在也可以通过引用来返回参数,并通过引用将它们存储在局部变量中。

  这个是非常有用的。例如,一个游戏可能会将它的数据保存在一个大的预分配数组结构中(为避免垃圾回收机制暂停)。这个方法可以直接返回一个引用到这样一个结构,且通过调用者可以读取和修改它。

  为确保安全,也有以下一些限制:

  • 你只能返回”安全返回”的引用:一个是传递给你的引用,一个是指向对象中的引用

  • 本地引用会被初始化成一个本地存储,并且不能指向另一个存储

  异步返回类型

  到目前为止,在C#的异步方法必须返回 void,Task 或 Task<T>。C#7.0 允许以这样的方式来定义其它类型,从而使它们可以从异步方法返回。

  例如,我们计划建立一个 ValueTask<T>结构类型的数据。建立它是为了防止 Task<T> 对象的分配时,异步操作的结果在等候是已可用。对于很多异步场景,比如以涉及缓冲为例,这可以大大减少分配的数量,并使性能有显著提升。

  注:异步返回类型尚未在 Preivew4 中提供。

  更多 Expression-bodied 成员

  Expression-bodied 的方法、属性等都是C# 6.0 的重大突破,但是不是所有的成员都可以使用的。 C#7.0 添加了访问器、构造函数和终结器等,使更多成员可以使用 Expression-bodied 方法:

  注:这些额外的 Expression-bodied 成员尚未在 Preview4 中提供。

  这是一个由社区共享的示例,而非微软 C# 团队提供的,它是开源的!

  Throw 表达式

  在表达式中间抛出一个异常是很容易的:只要调用一个方法!但在 C # 7.0 中,我们允许在一些地方直接抛出一个表达式:

  注:Throw 表达式尚未在 Preview 4 中提供。

原文地址:https://news.cnblogs.com/n/561619/


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值