将字典从一种类型转换为另一种类型

时间:2011-06-28 14:09:50

标签: .net generics dictionary types

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

该语言是VB.NET,但如果您对此感到满意,我可以阅读并转换C#。

2 个答案:

答案 0 :(得分:10)

我会使用Linq这样的案例。有一个ToDictionary()方法通过获取Enumerable元素的两个投影来生成字典的键和值,从而将任何通用IEnumerable(和Dictionary<TA,TB>IEnumerable<KeyValuePair<TA,TB>>)转换为Dictionary。它使这些类型的转换非常简单:

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<string,string>;在这种情况下,你只需要ToString()它们(如果你已经覆盖了那个方法)或者在一些String.Format操作中使用Key / Value。

答案 1 :(得分:4)

 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<TSource>.AllValuesAreUnique是一种扩展方法,我相信你可以弄清楚如何写。

然后,你可以说:

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

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

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