【问题标题】:KeyValuePair naming by ValueTuple in C# 7C# 7 中由 ValueTuple 命名的 KeyValuePair
【发布时间】:2017-09-03 02:08:10
【问题描述】:

C# 7.0(在 VS 2017 中)中的新功能是否可以将元组字段名称转换为 KeyValuePairs?

假设我有这个:

class Entry
{
  public string SomeProperty { get; set; }
}

var allEntries = new Dictionary<int, List<Entry>>();
// adding some keys with some lists of Entry

最好能做这样的事情:

foreach ((int collectionId, List<Entry> entries) in allEntries)

我已经在项目中添加了System.ValueTuple

能这样写就比这种传统风格好多了:

foreach (var kvp in allEntries)
{
  int collectionId = kvp.Key;
  List<Entry> entries = kvp.Value;
}

【问题讨论】:

  • 请提供minimal reproducible example。我们不知道allEntries 是什么,这让我们很难提供帮助......
  • @JonSkeet 我添加了更多关于这可能是哪种字典的数据,尽管问题很笼统,也可能是Dictionary&lt;int, string&gt;
  • 只是Dictionary&lt;,&gt; 的事实是一个好的开始 - 你之前没有提到过。我认为如果您使用Dictionary&lt;int, string&gt;minimal reproducible example 重写问题会更简单。我一会儿看看……

标签: c# dictionary c#-7.0 valuetuple


【解决方案1】:

解构需要在类型本身或作为扩展方法定义的Deconstruct 方法。 KeyValuePaire&lt;K,V&gt;本身没有Deconstruct方法,所以需要定义一个扩展方法:

static class MyExtensions
{
    public static void Deconstruct<K,V>(this KeyValuePair<K,V> kvp, out K key, out V value)
    {
      key=kvp.Key;
      value=kvp.Value;
    }
}

这允许你写:

var allEntries = new Dictionary<int, List<Entry>>();
foreach(var (key, entries) in allEntries)
{
    ...
}

例如:

var allEntries = new Dictionary<int, List<Entry>>{
    [5]=new List<Entry>{
                        new Entry{SomeProperty="sdf"},
                        new Entry{SomeProperty="sdasdf"}
                        },
    [11]=new List<Entry>{
                        new Entry{SomeProperty="sdfasd"},
                        new Entry{SomeProperty="sdasdfasdf"}
                        },    };
foreach(var (key, entries) in allEntries)
{
    Console.WriteLine(key);
    foreach(var entry in entries)
    {
        Console.WriteLine($"\t{entry.SomeProperty}");
    }
}

【讨论】:

  • 请注意KeyValuePair will have Deconstruct in .Net Core 2.0(可能还有一些未来版本的 .Net Standard 和 .Net Framework)。
  • 你确定这有效吗? Deconstruct 不应该允许以解构元组的方式解构类型。不进入元组。
  • 代码编译运行。此外,this sn-p 不会创建元组,它会将 KVP 解构为两个变量。这与What's new in C# 7 中的Point 示例没有什么不同。
  • 我认为这是不同的,因为Point 示例调用了一个方法,其中在参数调用中声明了输出参数,但这里的返回值是拆分的。不过也有相似之处。但是这篇文章需要一个合适的Deconstruct。最后,这只是语法糖,但我喜欢它。
  • @ZoolWay 和(var myX, var myY) = GetPoint(); class Point { /* ... */ public void Deconstruct(out int x, out int y) { x = X; y = Y; } }的代码完全一样,只是这里使用了扩展方法而不是类中的声明。
猜你喜欢
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
  • 2018-12-22
  • 1970-01-01
  • 2020-12-04
  • 2018-10-16
  • 2017-09-19
  • 1970-01-01
相关资源
最近更新 更多