字典中的 foreach 解构
Posted
技术标签:
【中文标题】字典中的 foreach 解构【英文标题】:Deconstruction in foreach over Dictionary 【发布时间】:2017-07-21 19:53:32 【问题描述】:在 C#7 中是否可以在字典上的 foreach 循环中使用解构?像这样的:
var dic = new Dictionary<string, int> ["Bob"] = 32, ["Alice"] = 17 ;
foreach (var (name, age) in dic)
Console.WriteLine($"name is age years old.");
它似乎不适用于 Visual Studio 2017 RC4 和 .NET Framework 4.6.2:
错误 CS1061:“KeyValuePair”不包含“Deconstruct”的定义,并且找不到接受“KeyValuePair”类型的第一个参数的扩展方法“Deconstruct”(您是否缺少 using 指令或程序集引用?)
【问题讨论】:
在 C# 扩展 1.23.16 的 VS Code 1.61.0 中,这仍然是一个问题。 【参考方案1】:首先你必须为KeyValuePair
添加一个扩展方法:
public static void Deconstruct<T1, T2>(this KeyValuePair<T1, T2> tuple, out T1 key, out T2 value)
key = tuple.Key;
value = tuple.Value;
然后你会得到一个不同的错误:
错误 CS8179:未定义或导入预定义类型“System.ValueTuple`2”
根据this answer你必须安装NuGet包System.ValueTuple
。
然后它应该编译。但是 Visual Studio 2017 RC4 会说它无法解析符号名称 name
和 age
。他们应该希望在未来的更新中解决这个问题。
【讨论】:
不知道为什么 RC4 会给你这个错误。name
和 age
解决得很好,当我尝试时代码可以工作。
所以static void Deconstruct<T1, T2>(this KeyValuePair<T1, T2>
将成为一种扩展方法,一旦 VS2017 下降,我将不得不在每个项目中一遍又一遍地编写?太棒了。
@Tinister:也许他们会在下周的版本中实现它。
@Tinister,为什么每次都重写?创建一个 nuget 包并将其导入到您的项目中...
@Tinister 你应该已经将你自己的可重用代码推送到你自己的库中【参考方案2】:
如果您不喜欢编写 Deconstruct
方法,特别是如果您只需要在一个地方使用它,以下是使用 LINQ 单行代码的方法:
使用您的原始字典:
var dic = new Dictionary<string, int> ["Bob"] = 32, ["Alice"] = 17 ;
你可以这样做:
foreach (var (name, age) in dic.Select(x => (x.Key, x.Value)))
Console.WriteLine($"name is age years old.");
【讨论】:
这也将在通过 LINQ 加入时起作用,当您最终获得一个匿名类时,结果中的每个模型都有一个字段;【参考方案3】:KeyValuePair<TKey,TValue>
中的Deconstruct
是 implemented in .NET Core 2.0,但不幸的是不在 .NET Framework(最高 4.8 预览版)中。
【讨论】:
对 KeyValuePair 的解构将包含在 .NET Standard 2.1 中 这就是为什么我的一些针对多个框架(包括 .net-core-2.0)的项目有时支持它而有时不支持。我以为我疯了。以上是关于字典中的 foreach 解构的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin集合操作 ③ ( List 集合遍历 | for in | forEach | forEachIndexed | List 通过解构一次性给多个元素赋值 )
Kotlin集合操作 ③ ( List 集合遍历 | for in | forEach | forEachIndexed | List 通过解构一次性给多个元素赋值 )