Я работаю в среде .NET 2.0. У меня работает некоторый код, просто хочу, чтобы он работал немного более элегантно.
Мне нужно эффективно «отразить» объект Dictionary, чтобы, если мы начнем с такого объекта, как этот
Dictionary<TKey,TValue> StartDictionary;
Мы можем отразить это так
Dictionary<TValue,TKey> MirroredDictionary = MirrorDictionary(StartDictionary);
И мы получим новый словарь с заменой значений и ключей для каждой KeyValuePair
Прежде чем кто-нибудь спросит меня, почему: исходный словарь достаточно велик и загружается один раз из вызовов отражений при загрузке моей программы. Я не хочу запускать одни и те же вызовы отражения во второй раз, чтобы загрузить зеркальный словарь. Создание зеркального словаря и заполнение его значений и ключей так, как я придумал, показалось мне гораздо менее затратным.
Таким образом, будучи человеком, который ненавидит переписывать вещи, я решил написать универсальный метод в классе помощника, я должен сделать Зеркало, используя Дженерики.
Теперь учтите, что я уже писал простые универсальные методы для нормальных скалярных типов
Вот что я придумал
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;
}
Немного там, но это работает, загружает типы ключей и значений и создает экземпляр зеркального словаря
Затем, просто просматривая базовые DictionaryEntries в InDictionary, он добавляет элементы в OutDic и возвращает его приведения к ожидаемому типу
Компилируется просто отлично
Теперь, когда я вызываю его, я думаю, точно так же, как когда я вызываю универсальный метод для скалярного типа, я мог бы просто использовать наши фрагменты кода выше, скажем
Dictionary<TValue,TKey> MirroredDictionary = MirrorDictionary(StartDictionary);
Но это не компилирует дает мне
Аргументы типа для метода MirrorDictionary (TInDic) 'не могут быть выведены из использования. Попробуйте указать аргументы типа явно.
Так что, если я вместо этого назову это
Dictionary<TValue, TKey> MirrorDic = MirrorDictionary<Dictionary<Tkey, TValue>, Dictionary<TValue,TKey>>(StringDic);
Он компилируется и работает как шарм.
Теперь возникает вопрос: как сделать так, чтобы он правильно выводил тип, передаваемый в этот метод, когда передаваемый тип и передаваемый тип являются сложными типами, как в этом примере?