C# 7 tuples and lambdas

瘦欲@ 提交于 2019-11-30 05:34:12

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.

You should specify names of tuple properties (well, ValueTuple have fields) otherwise default names will be used, as you have seen:

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

Now tuple have nicely named fields which you can use

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

Don't forget to add System.ValueTuple package from NuGet and keep in mind that ValueTuples are mutable structs.


Update: Deconstruction currently represented only as an assignment to existing variables (deconstructon-assignment) or to newly created local variables (deconstruction-declaration). Applicable function member selection algorithm is the same as before:

Each argument in argument list corresponds to a parameter in the function member declaration as described in §7.5.1.1, and any parameter to which no argument corresponds is an optional parameter.

Tuple variable is a single argument. It cannot correspond to several parameters in the formal parameters list of the method.

Deconstructions in C# 7.0 support three forms:

  • deconstruction-declaration (like (var x, var y) = e;),
  • deconstruction-assignment (like (x, y) = e;),
  • and deconstruction-foreach (like foreach(var(x, y) in e) ...).

Other contexts were considered, but likely have decreasing utility and we couldn't complete them in the C# 7.0 timeframe. Deconstruction in a let clause (let (x, y) = e ...) and in lambdas seem good candidates for future expansion.

The latter is being discussed in https://github.com/dotnet/csharplang/issues/258

Do voice your feedback and interest there, as it will help champion proposals.

More details on what was included in C# 7.0 deconstruction in the design doc.

The program you're running into is the inability of the compiler to infer the type in this expression:

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

But since (int, int) and (int x, int y) are the same CLR type (System.ValueType<int, int>), if you specify the type parameters:

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

It will work.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!