C# 7 tuples and lambdas

Rast picture Rast · Mar 29, 2017 · Viewed 14.3k times · Source

With new c# 7 tuple syntax, is it possible to specify a lambda with a tuple as parameter and use unpacked values inside the lambda?

Example:

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

normal way to use a tuple in lambda:

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

i expected some new sugar to avoid .Item1 .Item2, like:

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

The last line does not work because it is treated as two parameters for lambda. I am not sure if there is a way to do it actually.

EDIT:

I tried double parentesis in lambda definition and it didn't work: ((x,y)) => ..., and maybe it was stupid to try, but double parenthesis actually work here:

list.Add((1,2));

Also, my question is not quite about avoiding ugly default names .Item .Item2, it is about actual unpacking a tuple in lambda (and maybe why it's not implemented or not possible). If you came here for a solution to default names, read Sergey Berezovskiy's answer.

EDIT 2:

Just thought of a more general use case: is it possible (or why not) to "deconstruct" tuple passed to a method? Like this:

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

Instead of this:

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

Answer

David Arno picture David Arno · Mar 29, 2017

As you have observed, for:

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

One would at least expect to be able to do the following:

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

But the C# 7 compiler doesn't (yet) support this. It is also reasonable to desire sugar that would allow the following:

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

Foo(list[0]);

with the compiler converting Foo(list[0]); to Foo(list[0].Item1, list[0].Item2); automatically.

Neither of these is currently possible. However, the issue, Proposal: Tuple deconstruction in lambda argument list, exists on the dotnet/csharplang repo on GitHub, requesting that the language team consider these features for a future version of C#. Please do add your voices to that thread if you too would like to see support for this.