использование универсального словаря и/или сортировка с помощью IDictionary

У меня есть словарь, значение которого определяется во время выполнения. Я могу создать его как IDictionary и добавить к нему нормально, но я не могу сортировать. Есть ли способ создать его как Dictionary, чтобы я мог получить доступ к OrderBy, или есть другой способ отсортировать его как IDictionary?

void func (PropertyDescriptor prop)
{
  //Create dynamic dictionary
  Type GenericTypeDictionary = typeof(Dictionary<,>);
  Type SpecificTypeDictionary = GenericTypeDictionary.MakeGenericType(typeof(T), prop.PropertyType);
  var genericDictionary = Activator.CreateInstance(SpecificTypeDictionary) as IDictionary ;

  //Add some items to it
  //....

  //Sort items (this line doesn't compile)
  genericDictionary = genericDictionary.OrderBy(x => x.Value).ToDictionary(x => x.Key, x => x.Value);
}

person Brian    schedule 23.02.2013    source источник


Ответы (1)


Не обращая внимания на то, что то, что вы пытаетесь сделать, может не иметь смысла, вы можете просто создать адаптер с IDictionary на IEnumerable<DictionaryEntry>:

IEnumerable<DictionaryEntry> EnumerateEntries(IDictionary d)
{
    foreach (DictionaryEntry de in d) 
    {
        yield return de;
    }
}

// ...

genericDictionary = EnumerateEntries(genericDictionary).OrderBy(…).ToDictionary(…);

(По какой-то причине я не исследовал дальше, использование genericDictionary.Cast<DictionaryEntry>() вместо вспомогательного метода у меня не сработало, но это может быть причуда Mono.)

person millimoose    schedule 23.02.2013
comment
Но вы не можете отсортировать последовательность DictionaryEntry — и Key, и Value относятся к типу object, так что вы вернулись к исходной точке. - person Jon; 24.02.2013
comment
@ Джон Нет, не совсем. Вы можете разыграть Key или Value в IComparable, если знаете, что получите именно это. У вас может быть IComparer, связанный с PropertyDescriptor каким-то образом, который, как вы знаете, будет работать с этим свойством. (Ни один из них не является безопасным для типов, но в любом случае его нельзя сделать безопасным для типов, если вы работаете с PropertyDescriptors вместо использования Expression для описания свойств.) И в любом случае OrderBy на самом деле не накладывает никаких ограничений на сравнение. тип ключа, поэтому он обязательно скомпилируется. - person millimoose; 24.02.2013
comment
Хм... У меня сложилось впечатление, что OrderBy требует, чтобы TKey было IComparable, что на самом деле не так. Для записи он проверяет тип во время выполнения и дает ArgumentException, если это не IComparable. Так что +1 за возможность узнать что-то новое :) - person Jon; 24.02.2013