C# 7 tuples and lambdas

前端 未结 4 1225
[愿得一人]
[愿得一人] 2020-12-15 02:36

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         


        
相关标签:
4条回答
  • 2020-12-15 02:43

    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.

    0 讨论(0)
  • 2020-12-15 02:57

    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.

    0 讨论(0)
  • 2020-12-15 03:00

    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.

    0 讨论(0)
  • 2020-12-15 03:01

    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.

    0 讨论(0)
提交回复
热议问题