原文:https://blogs.msdn.microsoft.com/mazhou/2017/06/27/c-7-series-part-4-discards/

有时我们想要忽略一个方法返回的值,特别是那些out参数,一个典型的例子是检查一个字符串是否可以解析成另一种类型:

bool parsedValue;
if (bool.TryParse("TRUE", out parsedValue)) { /* 其他代码 */ }

这里我们要忽略parsedValue。我们还希望使这个变量不可访问,以便开发人员不能引用它。

C# 7.0有一个叫做discards(译注:官方翻译:弃元)的新特性,可以在这个场景中用来实现我们的目标。

弃元

弃元是可以赋值但不能从中读取的局部变量。也就是说,它们是“只写”的局部变量。它们没有名称,而是用_(下划线)表示。_是上下文关键字,与var非常相似,并且_不能被读取(即不能出现在赋值的右侧)。

如果我们将弃元应用到上面的代码,它将看起来像这样:

if (bool.TryParse("TRUE", out bool _)) { /* 其他代码 */ }

因为_是不可读的,所以它不会出现在IDE的智能感知中,也不会编译代码。

弃元适用的场景

  • 带有out修饰符的声明表达式,例如:bool.TryParse(“字符串”,out _)
  • 模式匹配子句,例如case int _ 或 if (x is string _)
  • 解构:
    • 在声明中:如var (a, _, c) = myObj
    • 在赋值:如var a, b;(a, b, _) = myObj
    • 值元组解构:例如 var (a, _, _) = (1,2,3)

关键字_

请始终记住_是一个上下文相关的关键字,就像var一样,这意味着如果您已经在当前上下文中声明了一个局部变量_,并且它位于作用域中,那么_将不是一个弃元,而是会在作用域中引用该局部变量。

更有趣的是,看看下面的代码:

bool _ = false, v = false;
if (bool.TryParse("TRUE", out var _))
{
v = _;
}

v的值是多少?

答案是false。if的条件为真,因为字符串“true”可以解析为一个布尔值true,但是这里我们用了out var _,这覆盖了前面声明的变量_的作用域,它是一个弃元。然后,if语句中的赋值v = _只读取前面声明的局部变量_的值(为false),并赋值给v,因此v的值为false。如果我们删除var来将代码更改为out _,那么v的值将为true,因为_不再是一个弃元了(译注:是一个普通变量),并且它保存了解析后的布尔值。

结论

C#中的弃元允许忽略一些局部变量。这是一个设计时特性,运行时可能仍然需要这个局部变量,编译器也可能为它生成一个名称。因为_关键字是上下文关键字,所以你需要设置一个编码策略来避免使用_作为名称声明局部变量以减少混淆。这个特性与早期的.NET版本兼容,因为它不需要更改CLR。

系列文章:

[译]C# 7系列,Part 4: Discards 弃元的更多相关文章

  1. [译]C# 7系列,Part 9: ref structs ref结构

    原文:https://blogs.msdn.microsoft.com/mazhou/2018/03/02/c-7-series-part-9-ref-structs/ 背景 在之前的文章中,我解释了 ...

  2. [译]C# 7系列,Part 8: in Parameters in参数

    原文:https://blogs.msdn.microsoft.com/mazhou/2018/01/08/c-7-series-part-8-in-parameters/ 背景 默认情况下,方法参数 ...

  3. [译]C# 7系列,Part 1: Value Tuples 值元组

    Mark Zhou写了很不错的一系列介绍C# 7的文章,虽然是2年多年前发布的,不过对于不熟悉C# 7特性的同学来说,仍然有很高的阅读价值. 原文:https://blogs.msdn.microso ...

  4. [译]C# 7系列,Part 2: Async Main 异步Main方法

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/05/30/c-7-series-part-2-async-main/ 你大概知道,C#语言可以构建两种 ...

  5. [译]C# 7系列,Part 3: Default Literals 默认文本表达式

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/06/06/c-7-series-part-3-default-literals/ C#的default ...

  6. [译]C# 7系列,Part 5: private protected 访问修饰符

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/10/05/c-7-series-part-5-private-protected/ C#有几个可访问性 ...

  7. [译]C# 7系列,Part 6: Read-only structs 只读结构

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/11/21/c-7-series-part-6-read-only-structs/ 背景 在.NET世 ...

  8. [译]C# 7系列,Part 7: ref Returns ref返回结果

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/12/12/c-7-series-part-7-ref-returns/ 背景 有两种方法可以将一个值传 ...

  9. [译]C# 7系列,Part 10: Span<T> and universal memory management Span<T>和统一内存管理

    原文:https://blogs.msdn.microsoft.com/mazhou/2018/03/25/c-7-series-part-10-spant-and-universal-memory- ...

随机推荐

  1. toString() 方法的参数

    除开null 和 undefined之外所有的数据类型都是拥有toString方法的. 通常情况下我们使用toString()方法的时候都是不用传递参数的,但是Number类型的toString方法是 ...

  2. Hystrix完整配置列表

    前提 Hystrix在2018年11月20日之后已经停止维护,最后一个提交记录是:Latest commit 3cb2158 on 20 Nov 2018,最后一个正式版本为1.5.18.鉴于目前所在 ...

  3. csrf与xss

    CSRF攻击攻击原理及过程如下: 1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A:       2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登 ...

  4. Vue组件通信之非父子组件传值

    前言: 如果想要了解非父子关系的组件传值,最好是在了解父传子和子传父的基础上在来了解非父子传值可能会有更透彻的思路. 因为非父子传值是通过定义事件总线来代理实现父传子+子传父从而实现的传值方式. 这是 ...

  5. C语言I博客作业01

    C语言I博客作业01 作业1 这个作业属于哪个课程? C语言程序设计I 这个作业要求在哪里? https://edu.cnblogs.com/campus/zswxy/CST2019-2/homewo ...

  6. Spring Data JPA 条件查询的关键字

    Spring Data JPA 为此提供了一些表达条件查询的关键字,大致如下: And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(Stri ...

  7. 2019-2020-6 20199317《Linux内核原理与分析》第六周作业

    第5章  系统调用的三层机制(下) 1  给MenuOS增加命令         首先进入LinuxKernel目录下,用rm -rf menu强制删除当前的menu目录,然后用git clone重新 ...

  8. Docker 构建私有仓库

    Docker Hub 目前Docker官方维护了一个公共仓库Docker Hub,其中已经包含了数量超过15000的镜像.大部分需求都可以通过在Docker Hub中直接下载镜像来实现. 可以在htt ...

  9. 使用正则表达式实现(加减乘除)计算器(C#实现)

    起因:公司领导要求做一款基于行业规范的计算器, 然后需要用户输入一些数据,然后根据用户输入的数据满足某些条件后,再根据用户输入的条件二进行加减乘除运算.;-) 期间因为查找规范等形成数据表的某一列是带 ...

  10. 自学PHP的第22天---ThinkPHP中的路由、ThinkPHP目录结构

    这一切的一切都得从“Hello world”说起!!! 有很多东西在thinkPHP的官方开发文档上其实都有讲到,我在这里只是想记录自己每天坚持学习PHP的情况,今天接触ThinkPHP的路由,路由这 ...