1. ホーム
  2. c#

[解決済み] C# 7 タプルとラムダ

2023-05-18 12:38:53

質問

c# 7の新しいタプル構文では、タプルをパラメータとしてラムダを指定し、ラムダ内でパックされていない値を使用することは可能でしょうか?

例を挙げます。

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

ラムダでタプルを使用する通常の方法です。

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

を回避するための新たな糖質を期待していたのですが .Item1 .Item2 のように。

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

最後の行は、lambdaの2つのパラメータとして扱われるため、動作しません。実際にやり方があるのかどうかはわかりません。

EDITです。

ラムダ定義で二重括弧を試してみましたが、うまくいきませんでした。 ((x,y)) => ... と、試したのがバカだったのか、ここでは実際に二重括弧が機能しています。

list.Add((1,2));

また、私の質問は醜いデフォルト名を避けることとは全く関係ありません。 .Item .Item2 についてではなく、ラムダで実際にタプルを展開することについてです(そして、なぜそれが実装されていないか、または不可能なのかもしれません)。もしあなたがデフォルト名に対する解決策を求めてここに来たのであれば、以下を読んでください。 Sergey Berezovskiyの回答です。 .

EDIT 2:

より一般的な使用例として、メソッドに渡されたタプルを "deconstruct"することは可能ですか (またはなぜ可能でないのでしょうか)。このように。

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); を自動生成します。

どちらも現状では不可能です。ただし、問題点として を提案する。ラムダ引数リストにおけるタプルの分解 に存在します。 dotnet/csharplang のレポがあり、言語チームがC#の将来のバージョンでこれらの機能を検討するよう要請しています。もしあなたもこのサポートを見たいのであれば、そのスレッドにあなたの声を追加してください。