Fred
Fred

Reputation: 607

iterate .net dictionary as object

I have an interesting problem. I need to write a general (I'd use the word "generic" but that would conflict with what I'm after) routine that I can hand an instance of a dictionary object instance and iterate over the content of said object as a dictionary and return the content as literal values. The difficulty lies in that the method parameter will be of type "object", not dictionary.

What I need now and can't figure out how to do, is a way of iterating over a Dictionary<K, V> of arbitrary keys and values. Easy to do if you know the types going in, but as I say, the origin of the dictionary will be as an object where object.GetType().GetInterfaces() has typeof(IDictionary) in the results. I won't know (and shouldn't need to know) the dictionary key type or the value type.

My current need is to process something that is Dictionary<string, SomeClass>;. Once I get the list of keys I can use a foreach on each instance, figure out that it's a string and proceed from there. With the Values it'll be an instance of some class (the class will change but again, I can pass that off to another set of methods to extract the class, extract the properties of the class and extract those values).

The main point of the request is to obtain a method (or two or however many) that will allow me to iterate over a dictionary of unknown types and extract the keys and values, all without knowing the types at compile time. The above Dictionary; is just an example, I need to be able to pass any dictionary. At the moment, I'm not worried about edge cases like Dictionary<Tuple<int, string, SomeOtherClass>, SomeClass>> or things like that, if I can start with Dictionary<string, SomeClass>;, I can probably proceed from there.

It's getting the keys and values out in a form that I can process that I haven't figured out how to do yet.

Upvotes: 1

Views: 1198

Answers (1)

metacubed
metacubed

Reputation: 7301

You mentioned that you have access to the IDictionary<K,V> interface on the object. You can then use get_Keys and get_Values to access the keys and values respectively.

Also, IDictionary<K,V> derives from IEnumerable<KeyValuePair<K,V>> so you can also access the list of key-value pairs using a for-loop similar to lists.

EDIT - Clarification:

IDictionary inputAsDictionary = input as IDictionary;
if (inputAsDictionary != null)
{
    // Valid :  input is a dictionary.
    ICollection dictKeys = inputAsDictionary.Keys; // This is a list of all keys
    ICollection dictValues = inputAsDictionary.Values; // This is a list of all values

    // Iterate over all keys
    for(var dictKey in dictKeys)
    {
        Console.WriteLine(dictKey); // Print the key
        Type dictKeyType = dictKey.GetType(); // Get the type of key if required
        // ...
    }

    // Similarly, iterate over all values
    for(var dictValue in dictValues)
    {
        Console.WriteLine(dictValue); // Print the value
        Type dictValueType = dictValue.GetType(); // Get the type of value if required
        // ...
    }
}

You can also do this using the generic Dictionary<K,V> interface, but it gets a lot more complicated to get the types. You will need to call Type.GenericTypeArguments and go from there. The example I have shown seems simpler.

Upvotes: 1

Related Questions