[译]C# 7系列,Part 4: Discards 弃元
原文: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 1: Value Tuples 值元组
- [译]C# 7系列,Part 2: Async Main 异步Main方法
- [译]C# 7系列,Part 3: Default Literals 默认文本表达式
- [译]C# 7系列,Part 4: Discards 弃元 (本文)
- [译]C# 7系列,Part 5: private protected 访问修饰符
- [译]C# 7系列,Part 6: Read-only structs 只读结构
- [译]C# 7系列,Part 7: ref Returns ref返回结果
- [译]C# 7系列,Part 8: in Parameters in参数
- [译]C# 7系列,Part 9: ref structs ref结构
- [译]C# 7系列,Part 10: Span<T> and universal memory management Span<T>和统一内存管理 (完)
[译]C# 7系列,Part 4: Discards 弃元的更多相关文章
- [译]C# 7系列,Part 9: ref structs ref结构
原文:https://blogs.msdn.microsoft.com/mazhou/2018/03/02/c-7-series-part-9-ref-structs/ 背景 在之前的文章中,我解释了 ...
- [译]C# 7系列,Part 8: in Parameters in参数
原文:https://blogs.msdn.microsoft.com/mazhou/2018/01/08/c-7-series-part-8-in-parameters/ 背景 默认情况下,方法参数 ...
- [译]C# 7系列,Part 1: Value Tuples 值元组
Mark Zhou写了很不错的一系列介绍C# 7的文章,虽然是2年多年前发布的,不过对于不熟悉C# 7特性的同学来说,仍然有很高的阅读价值. 原文:https://blogs.msdn.microso ...
- [译]C# 7系列,Part 2: Async Main 异步Main方法
原文:https://blogs.msdn.microsoft.com/mazhou/2017/05/30/c-7-series-part-2-async-main/ 你大概知道,C#语言可以构建两种 ...
- [译]C# 7系列,Part 3: Default Literals 默认文本表达式
原文:https://blogs.msdn.microsoft.com/mazhou/2017/06/06/c-7-series-part-3-default-literals/ C#的default ...
- [译]C# 7系列,Part 5: private protected 访问修饰符
原文:https://blogs.msdn.microsoft.com/mazhou/2017/10/05/c-7-series-part-5-private-protected/ C#有几个可访问性 ...
- [译]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世 ...
- [译]C# 7系列,Part 7: ref Returns ref返回结果
原文:https://blogs.msdn.microsoft.com/mazhou/2017/12/12/c-7-series-part-7-ref-returns/ 背景 有两种方法可以将一个值传 ...
- [译]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- ...
随机推荐
- [从今天开始修炼数据结构]线性表及其实现以及实现有Itertor的ArrayList和LinkedList
一.线性表 1,什么是线性表 线性表就是零个或多个数据元素的有限序列.线性表中的每个元素只能有零个或一个前驱元素,零个或一个后继元素.在较复杂的线性表中,一个数据元素可以由若干个数据项组成.比如牵手排 ...
- 【Luogu P1981】表达式求值
点我进入原题Luogu P1981 [解题思路] 仔细分析题目,这就是一道模拟题…… 直接按照符号读入全部的数字,先算乘法,最后把全部数加起来就是结果了 记得要%10000取最后四位 [参考程序] # ...
- 闲来无事写了一套 Jenkins 主题样式:刀锋
背景 Jenkins 的前端 CSS 样式坚挺了这么多年已经觉得腻的不行了,于是想换个风格缓解一下视觉疲劳,便有了这个项目.由于本人不是前端,所以很多只是随便改改,有些复杂的需求也实现不了,但是总的来 ...
- React躬行记(15)——React Hooks
Hook(钩子)是React v16.8新引入的特性,能以钩子的形式为函数组件附加类组件的状态.生命周期等特性.React的类组件有难以拆分.测试,状态逻辑分散,难以复用等问题,虽然可以通过渲染属性( ...
- 原生线程池这么强大,Tomcat 为何还需扩展线程池?
前言 Tomcat/Jetty 是目前比较流行的 Web 容器,两者接受请求之后都会转交给线程池处理,这样可以有效提高处理的能力与并发度.JDK 提高完整线程池实现,但是 Tomcat/Jetty 都 ...
- 品优购详情页---产品详细信息区域 iteminfo_wrap
产品详细信息区域为整个大盒子命名为: iteminfo_wrap 1号盒子命名为:sku_name 2号盒子命名为:news 3号盒子命名为:summary step1:3个盒子搭建框架,以及完成前两 ...
- uni-app中使用scroll-view滚到底部时多次触发scrolltolower事件
一.前言.scroll-view基本属性: 前言: 前段时间使用scroll-view可滚动视图区域容器来做多个不同内容的展示(在我这个页面中同时使用了三个scroll-view做数据展示),因为这几 ...
- CarbonData:大数据融合数仓新一代引擎
[摘要] CarbonData将存储和计算逻辑分离,通过索引技术让存储和计算物理上更接近,提升CPU和IO效率,实现超高性能的大数据分析.以CarbonData为融合数仓的大数据解决方案,为金融转型打 ...
- 源码分析 RocketMQ DLedger 多副本存储实现
目录 1.DLedger 存储相关类图 1.1 DLedgerStore 1.2 DLedgerMemoryStore 1.3 DLedgerMmapFileStore 2.DLedger 存储 对标 ...
- 二叉树的建立&&前中后遍历(递归实现)&&层次遍历
下面代码包含了二叉树的建立过程,以及三种遍历方法了递归实现,代码中还利用队列实现了层次遍历. import java.util.LinkedList; import java.util.Queue; ...