[译]C# 7系列,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。
系列文章:
上一篇: PHP+jQuery实现即点即改功能示例
下一篇: 优减创始人郭蓉:创业需要拼尽全力
推荐阅读
-
[译]C# 7系列,Part 9: ref structs ref结构
-
[译]C# 7系列,Part 4: Discards
-
[译]C# 7系列,Part 2: Async Main
-
[译]C# 7系列,Part 5: private protected 访问修饰符
-
[译]C# 7系列,Part 6: Read-only structs 只读结构
-
[译]C# 7系列,Part 1: Value Tuples
-
[译]C# 7系列,Part 10: Span
and universal memory management Span 和统一内存管理 -
[译]C# 7系列,Part 3: Default Literals
-
[译]C# 7系列,Part 8: in Parameters in参数
-
[译]C# 7系列,Part 7: ref Returns ref返回结果