I am working in the .NET 2.0 framework. I have some code working, just want it working a little more elegantly.
I have a need to effectively “mirror” a Dictionary object such that if we start with an object like this
Dictionary<TKey,TValue> StartDictionary;
We can Mirror it like this
Dictionary<TValue,TKey> MirroredDictionary = MirrorDictionary(StartDictionary);
And we would end up with a new dictionary with the values and keys being swapped for each KeyValuePair
Before anyone asks me why: the source dictionary is fairly large and loaded once from reflection calls when my program loads. I don’t want to run the same reflection calls a second time to load the mirrored dictionary. Creating a mirrored Dictionary and populating its values and keys the way I came up with seemed to me to be much less costly.
So being the kind of person that hates to rewrite things, I decided to write a Generic method in a helper class I have to do the Mirror using Generics.
Now mind you I’ve written simple Generic methods before for normal scalar types
Here’s what I came up with
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;
}
A little bit there but it works, Loads up the Types of the Keys and Values and creates an instance of the mirrored Dictionary
Then just looping through the base DictionaryEntries of the InDictionary it adds the items to the OutDic and returns it casting it to the Type expected
Compiles just fine
Now when i go to call it I would think just like when i call a Generic method for a scalar type I could just using our code snippits above say
Dictionary<TValue,TKey> MirroredDictionary = MirrorDictionary(StartDictionary);
But that does not compile gives me
The type arguments for method MirrorDictionary(TInDic)’ cannot be inferred from the usage. Try specifying the type arguments explicitly.
So If I call it instead like this
Dictionary<TValue, TKey> MirrorDic = MirrorDictionary<Dictionary<Tkey, TValue>, Dictionary<TValue,TKey>>(StringDic);
It compiles and works like a charm.
Now the question becomes how do I make it properly infer the Type being passed into this method when the Type being passed in and the Type being passed out are complex types like in this example?
You can make life much easier for the compiler by telling it the key and value types thus:
I don’t think you need reflection here at all.
Sample usage:
where
DumpDicis: