【问题标题】:Converting a Dictionary from one type to another将字典从一种类型转换为另一种类型
【发布时间】:2011-09-24 08:50:08
【问题描述】:

如何将Dictionary(Of TypeA, TypeB) 转换为Dictionary(Of TypeC, TypeD)?转换时有一个隐式转换(假设第二个字典是String, String),所以这个过程应该是自动的,对吧?我只是想不出一个优雅的方法来做到这一点。

语言是 VB.NET,但如果你更习惯的话,我可以阅读和转换 C#。

【问题讨论】:

  • 您能更具体地说明您要做什么吗?据我了解,您希望您的字典同时支持 TypeA/TypeC 和 TypeB/TypeD 吗? TypeC 和 TypeD 分别是 TypeA 和 TypeB 的派生版本吗?

标签: .net generics dictionary types


【解决方案1】:

我会在这样的情况下使用 Linq。有一个 ToDictionary() 方法可以将任何通用 IEnumerable(Dictionary<TA,TB>IEnumerable<KeyValuePair<TA,TB>>)转换为 Dictionary,方法是对 Enumerable 元素进行两次投影以生成字典的键和值。它使这些类型的转换非常简单:

Dictionary<TypeA, TypeB> myDictionary = new Dictionary<TypeA, TypeB>
                                            { 
                                               /*initialization here*/ 
                                            };
Dictionary<TypeC, TypeD> myChangedDictionary = 
    myDictionary.ToDictionary(x=>x.Key.AsTypeC(), x=>x.Value.AsTypeD())

AsTypeC() 和 AsTypeD() 是从 A/B 到 C/D 所需的任何转换的占位符。你建议第二个字典是Dictionary&lt;string,string&gt;;在这种情况下,您只需使用 ToString() (如果您已覆盖该方法)或在某些 String.Format 操作中使用键/值。

【讨论】:

  • ToDictionary 是我最终使用的单行解决方案,因为生成的字典只是
  • 谢谢!。它节省了我一小时。
【解决方案2】:
 public static class DictionaryExtensions {
     public static Dictionary<TProjectedKey, TProjectedValue> ConvertDictionary<
         TKey,
         TValue,
         TProjectedKey, 
         TProjectedValue
     >(
         this Dictionary<TKey, TValue> dictionary,
         Func<TKey, TProjectedKey> keyProjection,
         Func<TValue, TProjectedValue> valueProjection
     ) {
         Contract.Requires(dictionary != null);
         Contract.Requires(keyProjection != null);
         Contract.Requires(valueProjection != null);
         Contract.Requires(dictionary.Select(kvp => keyProjection(kvp.Key))
                                     .AllValuesAreUnique()
                          );
         return dictionary.ToDictionary(
             kvp => keyProjection(kvp.Key),
             kvp => valueProjection(kvp.Value)
         );
     }
 }

最后一个Contract.Requires 表示keyProjection 必须与dictionary.Keys 一对一。方法IEnumerable&lt;TSource&gt;.AllValuesAreUnique 是一个扩展方法,相信你一定能猜到怎么写。

那么,你可以说:

Dictionary<Foo, Bar> dictionary = // some dictionary;
var projection = dictionary.ConvertDictionary(
    foo => foo.ToString(),
    bar => bar.ToString()
);

所以这个过程应该是自动的,对吧?

我看不出为什么这应该是自动的。如果类型不同,它们的哈希码可能不同等。“转换后的”字典实际上需要从头开始构建。

【讨论】:

  • 我们所做的比Project 更多的是Convert,你不是说吗?
  • @AakashM:当然,我改了名字。谢谢。
  • 你明白这种扩展方式是多余的; Linq 库已经有一个用于 IEnumerables 的 ToDictionary() 方法(并且 Dictionary 是一个 IEnumerable),其工作方式相同。
猜你喜欢
  • 1970-01-01
  • 2012-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-14
  • 1970-01-01
  • 1970-01-01
  • 2020-05-27
相关资源
最近更新 更多