簡體   English   中英

C# 7 元組和 lambdas

[英]C# 7 tuples and lambdas

使用新的 c# 7 元組語法,是否可以指定一個帶有元組作為參數的 lambda 並在 lambda 中使用解壓值?

例子:

var list = new List<(int,int)>();

在 lambda 中使用元組的正常方法:

list.Select(value => value.Item1*2 + value.Item2/2);

我希望一些新的糖可以避免.Item1 .Item2 ,例如:

list.Select((x,y) => x*2 + y/2);

最后一行不起作用,因為它被視為 lambda 的兩個參數。 我不確定是否有辦法真正做到這一點。

編輯:

我在 lambda 定義中嘗試了雙括號,但沒有奏效: ((x,y)) => ... ,也許嘗試起來很愚蠢,但雙括號實際上在這里起作用:

list.Add((1,2));

另外,我的問題並不是關於避免丑陋的默認名稱.Item .Item2 ,而是關於在 lambda 中實際解包一個元組(也許為什么它沒有實現或不可能實現)。 如果您來這里是為了解決默認名稱,請閱讀Sergey Berezovskiy 的回答

編輯2:

只是想到了一個更一般的用例:是否有可能(或為什么不)“解構”傳遞給方法的元組? 像這樣:

void Foo((int,int)(x,y)) { x+y; }

取而代之的是:

void Foo((int x,int y) value) { value.x+value.y }

正如您所觀察到的,對於:

var list = new List<(int,int)>();

人們至少希望能夠做到以下幾點:

list.Select((x,y) => x*2 + y/2);

但是 C# 7 編譯器(還)不支持這一點。 需要糖以允許以下內容也是合理的:

void Foo(int x, int y) => ...

Foo(list[0]);

與編譯器轉換Foo(list[0]); Foo(list[0].Item1, list[0].Item2); 自動地。

目前這兩種方法都不可能。 但是,GitHub 上的dotnet/csharplang庫中存在問題Proposal: Tuple deconstruction in lambda argument list ,要求語言團隊在 C# 的未來版本中考慮這些功能。 如果您也希望看到對此的支持,請務必將您的聲音添加到該線程中。

您應該指定元組屬性的名稱(好吧,ValueTuple 有字段),否則將使用默認名稱,如您所見:

var list = new List<(int x, int y)>();

現在元組有很好命名的字段,您可以使用

list.Select(t => t.x * 2 + t.y / 2)

不要忘記從 NuGet 添加System.ValueTuple包,並記住 ValueTuples 是可變結構。


更新:解構當前僅表示為對現有變量(解構賦值)或新創建的局部變量(解構聲明)的賦值。 適用的函數成員選擇算法與之前相同:

參數列表中的每個參數對應於第 7.5.1.1 節中描述的函數成員聲明中的一個參數,任何沒有參數對應的參數都是可選參數。

元組變量是單個參數。 它不能對應方法的形參列表中的幾個參數。

C# 7.0 中的解構支持三種形式:

  • 解構聲明(如(var x, var y) = e; ),
  • 解構賦值(如(x, y) = e; ),
  • 和 deconstruction-foreach (如foreach(var(x, y) in e) ... )。

考慮了其他上下文,但實用性可能會下降,我們無法在 C# 7.0 時間范圍內完成它們。 let 子句( let (x, y) = e ... )和 lambdas 中的解構似乎是未來擴展的好候選者。

后者正在https://github.com/dotnet/csharplang/issues/258中討論

請在那里表達您的反饋和興趣,因為這將有助於支持提案。

有關設計文檔中 C# 7.0 解構中包含的內容的更多詳細信息。

您遇到的問題是編譯器無法推斷此表達式中的類型:

list.Select(((int x, int y) t) => t.x * 2 + t.y / 2);

但由於(int, int)(int x, int y)是相同的 CLR 類型( System.ValueType<int, int> ),如果您指定類型參數:

list.Select<(int x, int y), int>(t => t.x * 2 + t.y / 2);

它會起作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM