C# 7 元组和 lambda
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 中实际解包一个元组(也许为什么它没有实现或不可能)。如果您是来这里寻找默认名称的解决方案,请阅读 。
编辑 2:
只是想到了一个更一般的用例:是否可以(或为什么不可以)将 "deconstruct" 元组传递给方法?像这样:
void Foo((int,int)(x,y)) { x+y; }
而不是这个:
void Foo((int x,int y) value) { value.x+value.y }
您应该指定元组属性的名称(嗯,ValueTuple 有字段)否则将使用默认名称,如您所见:
var list = new List<(int x, int y)>();
现在元组有很好命名的字段供您使用
list.Select(t => t.x * 2 + t.y / 2)
不要忘记从 NuGet 添加 System.ValueTuple 包,并记住 ValueTuples 是可变结构。
更新:解构目前仅表示为对现有变量的赋值(解构赋值)或对新创建的局部变量(解构声明)的赋值。适用函数成员选择算法同前:
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.
元组变量是单个参数。不能对应方法形参列表中的多个参数
您 运行 遇到的问题是编译器无法推断此表达式中的类型:
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);
它会起作用。
如您所见,对于:
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);
。
这些目前都不可能。但是,问题 Proposal: Tuple deconstruction in lambda argument list 存在于 GitHub 的 dotnet/csharplang
存储库中,要求语言团队在未来的 C# 版本中考虑这些功能。如果您也希望看到对此的支持,请将您的声音添加到该主题中。
C# 7.0 中的解构支持三种形式:
- 解构声明(如
(var x, var y) = e;
),
- 解构赋值(如
(x, y) = e;
),
- 和解构-foreach(如
foreach(var(x, y) in e) ...
)。
考虑了其他上下文,但实用性可能会降低,我们无法在 C# 7.0 时间范围内完成它们。 let 子句 (let (x, y) = e ...
) 和 lambda 中的解构似乎是未来扩展的好候选。
后者正在 https://github.com/dotnet/csharplang/issues/258
中讨论
请在那里表达您的反馈和兴趣,因为这将有助于支持提案。
有关 design doc 中 C# 7.0 解构中包含的内容的更多详细信息。
使用新的 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 中实际解包一个元组(也许为什么它没有实现或不可能)。如果您是来这里寻找默认名称的解决方案,请阅读
编辑 2:
只是想到了一个更一般的用例:是否可以(或为什么不可以)将 "deconstruct" 元组传递给方法?像这样:
void Foo((int,int)(x,y)) { x+y; }
而不是这个:
void Foo((int x,int y) value) { value.x+value.y }
您应该指定元组属性的名称(嗯,ValueTuple 有字段)否则将使用默认名称,如您所见:
var list = new List<(int x, int y)>();
现在元组有很好命名的字段供您使用
list.Select(t => t.x * 2 + t.y / 2)
不要忘记从 NuGet 添加 System.ValueTuple 包,并记住 ValueTuples 是可变结构。
更新:解构目前仅表示为对现有变量的赋值(解构赋值)或对新创建的局部变量(解构声明)的赋值。适用函数成员选择算法同前:
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.
元组变量是单个参数。不能对应方法形参列表中的多个参数
您 运行 遇到的问题是编译器无法推断此表达式中的类型:
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);
它会起作用。
如您所见,对于:
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);
。
这些目前都不可能。但是,问题 Proposal: Tuple deconstruction in lambda argument list 存在于 GitHub 的 dotnet/csharplang
存储库中,要求语言团队在未来的 C# 版本中考虑这些功能。如果您也希望看到对此的支持,请将您的声音添加到该主题中。
C# 7.0 中的解构支持三种形式:
- 解构声明(如
(var x, var y) = e;
), - 解构赋值(如
(x, y) = e;
), - 和解构-foreach(如
foreach(var(x, y) in e) ...
)。
考虑了其他上下文,但实用性可能会降低,我们无法在 C# 7.0 时间范围内完成它们。 let 子句 (let (x, y) = e ...
) 和 lambda 中的解构似乎是未来扩展的好候选。
后者正在 https://github.com/dotnet/csharplang/issues/258
中讨论请在那里表达您的反馈和兴趣,因为这将有助于支持提案。
有关 design doc 中 C# 7.0 解构中包含的内容的更多详细信息。