原文: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>和統一記憶體管理 (完)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/93233.html
標籤:C#
