我在.NET 2.0框架中工作。我有一些代码工作,只是希望它更优雅地工作。
我需要有效地“镜像”一个Dictionary对象,这样如果我们从像这样的对象开始
Dictionary<TKey,TValue> StartDictionary;
我们可以像这样镜像
Dictionary<TValue,TKey> MirroredDictionary = MirrorDictionary(StartDictionary);
我们最终会得到一个新词典,每个KeyValuePair都会交换值和键
在有人问我原因之前:源代码很大并且在我的程序加载时从反射调用加载一次。我不想再次运行相同的反射调用来加载镜像字典。在我看来,创建一个镜像词典并按照我提出的方式填充其值和键,可以降低成本。
因此,作为那种不喜欢重写事物的人,我决定在帮助器类中编写一个Generic方法,我必须使用Generics来做Mirror。
现在请注意,我之前为普通标量类型编写了简单的通用方法
这就是我提出的
public static TOutDic MirrorDictionary<TInDic, TOutDic>(TInDic InDictionary)
where TInDic : IDictionary
where TOutDic : IDictionary
{
Type[] KVPTypes = typeof(TInDic).GetGenericArguments();
Type TKey = KVPTypes[0];
Type TValue = KVPTypes[1];
Type TDic = typeof(Dictionary<,>).MakeGenericType(TValue, TKey);
IDictionary OutDic = (IDictionary)Activator.CreateInstance(TDic);
foreach (DictionaryEntry DE in (IDictionary)InDictionary) OutDic.Add(DE.Value, DE.Key);
return (TOutDic)OutDic;
}
稍微有点但它有效,加载键和值的类型并创建镜像词典的实例
然后循环遍历InDictionary的基本DictionaryEntries,它将项添加到OutDic并返回它,将其转换为预期的类型
编译得很好
现在,当我去打电话的时候,我会想到,当我为标量类型调用Generic方法时,我可以使用上面的代码snippits说
Dictionary<TValue,TKey> MirroredDictionary = MirrorDictionary(StartDictionary);
但那不能编译给我
无法从用法推断出MirrorDictionary(TInDic)方法的类型参数。尝试明确指定类型参数。
所以如果我这样称呼它
Dictionary<TValue, TKey> MirrorDic = MirrorDictionary<Dictionary<Tkey, TValue>, Dictionary<TValue,TKey>>(StringDic);
它的编辑和工作就像一个魅力。
现在的问题是,当传入Type并且传递出的Type是这个例子中的复杂类型时,如何正确推断传递给此方法的Type?
答案 0 :(得分:1)
这是一个3.5解决方案(你也可以在VS2008和LinqBridge的2.0中使用它)
IDictionary<TValue, TKey> MirrorDictionary<TKey, TValue>(IDictionary<TKey, TValue> dict)
{
return dict.ToDictionary(kvp => kvp.Value, kvp => kvp.Key);
}
纯粹的2.0解决方案
IDictionary<TValue, TKey> MirrorDictionary<TKey, TValue>(IDictionary<TKey, TValue> dict)
{
Dictionary<TValue, TKey> newDict = new Dictionary<TValue, TKey>();
foreach(KeyValuePair<TKey, TValue> kvp in dict)
{
newDict.Add(kvp.Value, kvp.Key);
}
return newDict;
}
类型推断应该适用于两种解决方案(因为它们具有相同的签名)
答案 1 :(得分:1)
通过告诉编码器键和值类型,可以使编译器的生活更轻松:
public static Dictionary<TValue, TKey> MirrorDictionary<TKey, TValue>
(Dictionary<TKey, TValue> source)
{
Dictionary<TValue, TKey> destination = new Dictionary<TValue, TKey>();
foreach (KeyValuePair<TKey, TValue> kvp in source)
{
destination.Add(kvp.Value, kvp.Key);
}
return destination;
}
我认为你根本不需要反思。
样本用法:
static void Main(string[] args)
{
Dictionary<int, string> source = new Dictionary<int, string>();
source.Add(3, "foo");
source.Add(4, "bar");
DumpDic(source);
DumpDic(MirrorDictionary(source));
Console.ReadLine();
}
其中DumpDic
是:
public static void DumpDic<TK, TV>(Dictionary<TK, TV> dic)
{
foreach (KeyValuePair<TK, TV> keyValuePair in dic)
{
Console.WriteLine("{0} => {1}", keyValuePair.Key, keyValuePair.Value);
}
}
答案 2 :(得分:0)
您可以将Out字典定义为out
参数。类型推断不会查看您要分配的变量的类型,只会查看参数的类型。这就是无法编译的原因。
答案 3 :(得分:0)
你需要告诉它TValue和TKey是什么。除非它们在调用此代码的方法的签名中定义,否则它们没有任何特定类型。你需要给它类似的东西:
Dictionary<string, int> MirroredDictionary = MirrorDictionary(StartDictionary);