Ras*_*ast 56 c# lambda tuples c#-7.0
使用新的c#7元组语法,是否可以指定一个带有元组作为参数的lambda并在lambda中使用解压缩的值?
例:
var list = new List<(int,int)>();
Run Code Online (Sandbox Code Playgroud)
在lambda中使用元组的常规方法:
list.Select(value => value.Item1*2 + value.Item2/2);
Run Code Online (Sandbox Code Playgroud)
我期待一些新的糖可以避免.Item1 .Item2,例如:
list.Select((x,y) => x*2 + y/2);
Run Code Online (Sandbox Code Playgroud)
最后一行不起作用,因为它被视为lambda的两个参数.我不确定是否有办法实际做到这一点.
编辑:
我尝试在lambda定义中进行双重注射,但它不起作用((x,y)) => ...,并且尝试可能是愚蠢的,但是双括号实际上在这里工作:
list.Add((1,2));
Run Code Online (Sandbox Code Playgroud)
另外,我的问题并不是关于避免丑陋的默认名称.Item .Item2,而是关于实际解压缩lambda中的元组(也许是为什么它没有实现或不可能).如果您来这里寻找默认名称的解决方案,请阅读Sergey Berezovskiy的回答.
编辑2:
刚想到一个更通用的用例:是否有可能(或者为什么不)将"解构"传递给方法的元组?像这样:
void Foo((int,int)(x,y)) { x+y; }
Run Code Online (Sandbox Code Playgroud)
而不是这个:
void Foo((int x,int y) value) { value.x+value.y }
Run Code Online (Sandbox Code Playgroud)
Dav*_*rno 34
正如您所观察到的,对于:
var list = new List<(int,int)>();
Run Code Online (Sandbox Code Playgroud)
人们至少希望能够做到以下几点:
list.Select((x,y) => x*2 + y/2);
Run Code Online (Sandbox Code Playgroud)
但是C#7编译器(尚未)支持这一点.希望糖能够满足以下要求是合理的:
void Foo(int x, int y) => ...
Foo(list[0]);
Run Code Online (Sandbox Code Playgroud)
与编译器转换Foo(list[0]);到Foo(list[0].Item1, list[0].Item2);自动.
目前这两种情况都不可能.然而,问题,提议:lambda参数列表中的元组解构,存在dotnet/csharplang于GitHub 上的repo中,要求语言团队将这些特性考虑为未来版本的C#.如果您也希望看到支持,请将您的声音添加到该主题.
Ser*_*kiy 28
您应该指定元组属性的名称(嗯,ValueTuple有字段),否则将使用默认名称,如您所见:
var list = new List<(int x, int y)>();
Run Code Online (Sandbox Code Playgroud)
现在元组已经很好地命名了你可以使用的字段
list.Select(t => t.x * 2 + t.y / 2)
Run Code Online (Sandbox Code Playgroud)
不要忘记从NuGet 添加System.ValueTuple包,并记住ValueTuples是可变结构.
更新:解构当前仅表示为对现有变量(解构结构赋值)或新创建的局部变量(解构 - 声明)的赋值.适用的功能成员选择算法与以前相同:
参数列表中的每个参数对应于§7.5.1.1中描述的函数成员声明中的参数,并且无参数对应的任何参数都是可选参数.
元组变量是一个参数.它不能对应于方法的形式参数列表中的几个参数.
C#7.0中的解构支持三种形式:
(var x, var y) = e;),(x, y) = e;),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);
Run Code Online (Sandbox Code Playgroud)
但是由于(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);
Run Code Online (Sandbox Code Playgroud)
它会起作用。
| 归档时间: |
|
| 查看次数: |
9623 次 |
| 最近记录: |