2

I have a dictionary where the value is determined at runtime. I can create it as an IDictionary and add to it fine however I can't sort. Is there a way to create it as a Dictionary so I can access OrderBy or is there another way to sort it as an 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);
}
levelnis
  • 7,665
  • 6
  • 37
  • 61
Brian
  • 21
  • 2
  • possible duplicate of [How do you sort a C# dictionary by value?](http://stackoverflow.com/questions/289/how-do-you-sort-a-c-sharp-dictionary-by-value) – Tim Schmelter Feb 23 '13 at 21:17
  • 2
    Won't sorting a dictionary then calling `ToDictionary()` just end up with the items in a random-ish order anyway? – millimoose Feb 23 '13 at 21:23
  • The link of Tim works only if your Dictionary is generic for both Keys and Values. Is is possible to make PropertyDescriptor prop as a generic member, so you can use a specificDictionary as a Dictionary ? – Larry Feb 23 '13 at 21:26

1 Answers1

4

Ignoring the point that what you're trying to do might not make sense, you can just create an adapter from IDictionary to IEnumerable<DictionaryEntry>:

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

// ...

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

(For some reason I didn't investigate further, using genericDictionary.Cast<DictionaryEntry>() instead of the helper method didn't work for me, but that might be a Mono quirk.)

millimoose
  • 39,073
  • 9
  • 82
  • 134
  • But you can't sort a sequence of `DictionaryEntry` -- both `Key` and `Value` are of type `object`, so you 're back to square one. – Jon Feb 23 '13 at 21:33
  • @Jon No, not really. You could cast `Key` or `Value` to `IComparable` if you know that's what you're going to get. You could have an `IComparer` associated with the `PropertyDescriptor` somehow that you know will work with that property. (None of these are type-safe, but can't really be made type-safe anyway if you're working with `PropertyDescriptors` instead of using `Expression`s to describe properties.) And either way `OrderBy` doesn't actually place any constraints on the comparison key type, so it will definitely compile. – millimoose Feb 23 '13 at 21:37
  • Hmm... I was under the impression that `OrderBy` required `TKey` to be `IComparable`, which indeed it does not. For the record, it checks the type at runtime and gives an `ArgumentException` if it's not an `IComparable`. So +1 for the opportunity to learn something new :) – Jon Feb 23 '13 at 21:43