繁体   English   中英

C# 7 元组和 lambdas

[英]C# 7 tuples and lambdas

使用新的 c# 7 元组语法,是否可以指定一个带有元组作为参数的 lambda 并在 lambda 中使用解压值?

例子:

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

在 lambda 中使用元组的正常方法:

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

我希望一些新的糖可以避免.Item1 .Item2 ,例如:

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

最后一行不起作用,因为它被视为 lambda 的两个参数。 我不确定是否有办法真正做到这一点。

编辑:

我在 lambda 定义中尝试了双括号,但没有奏效: ((x,y)) => ... ,也许尝试起来很愚蠢,但双括号实际上在这里起作用:

list.Add((1,2));

另外,我的问题并不是关于避免丑陋的默认名称.Item .Item2 ,而是关于在 lambda 中实际解包一个元组(也许为什么它没有实现或不可能实现)。 如果您来这里是为了解决默认名称,请阅读Sergey Berezovskiy 的回答

编辑2:

只是想到了一个更一般的用例:是否有可能(或为什么不)“解构”传递给方法的元组? 像这样:

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); 自动地。

目前这两种方法都不可能。 但是,GitHub 上的dotnet/csharplang库中存在问题Proposal: Tuple deconstruction in lambda argument list ,要求语言团队在 C# 的未来版本中考虑这些功能。 如果您也希望看到对此的支持,请务必将您的声音添加到该线程中。

您应该指定元组属性的名称(好吧,ValueTuple 有字段),否则将使用默认名称,如您所见:

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

现在元组有很好命名的字段,您可以使用

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

不要忘记从 NuGet 添加System.ValueTuple包,并记住 ValueTuples 是可变结构。


更新:解构当前仅表示为对现有变量(解构赋值)或新创建的局部变量(解构声明)的赋值。 适用的函数成员选择算法与之前相同:

参数列表中的每个参数对应于第 7.5.1.1 节中描述的函数成员声明中的一个参数,任何没有参数对应的参数都是可选参数。

元组变量是单个参数。 它不能对应方法的形参列表中的几个参数。

C# 7.0 中的解构支持三种形式:

  • 解构声明(如(var x, var y) = e; ),
  • 解构赋值(如(x, y) = e; ),
  • 和 deconstruction-foreach (如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);

但由于(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);

它会起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM