nickolayratchev
nickolayratchev

Reputation: 1206

Get dictionary key-value pairs without knowing its type

I have an object instance for which

instance.GetType().GetGenericTypeDefinition() == typeof(Dictionary<,>)

is true. My question is, how can I extract the key-value pairs from this object without actually knowing their generic types? I would like to get something like KeyValuePair<object, object>[]. Note that I also know the generic types the dictionary uses at runtime (but not compile-time). I assume some kind of reflection is required?

FOLLOW-UP: Is there a general mechanism to convert an object to SomeClass<> (if I know that is the correct type, of course) and thus use it, given that the implementation of the class is not affected by the type of generic arguments?

Upvotes: 9

Views: 14440

Answers (3)

Arvo Bowen
Arvo Bowen

Reputation: 4929

This is what I came up with to help me out. It suited my needs at the time... Maybe it will help someone else out.

foreach (var unknown in (dynamic)savedState)
{
  object dKey = unknown.Key;
  object dValue = unknown.Value;

  switch (dKey.GetType().ToString())
  {
    case "System.String":
      //Save the key
      sKey = (string)dKey;

      switch (dValue.GetType().ToString())
      {
        case "System.String":
          //Save the string value
          sValue = (string)dValue;

          break;
        case "System.Int32":
          //Save the int value
          sValue = ((int)dValue).ToString();

          break;
      }

      break;
  }

  //Show the keypair to the global dictionary
  MessageBox.Show("Key:" + sKey + " Value:" + sValue);
}

Upvotes: 1

Dimitar Dimitrov
Dimitar Dimitrov

Reputation: 15138

I would do what Jeremy Todd said except maybe a little bit shorter:

    foreach(var item in (dynamic)instance)
    {
       object key = item.Key;
       object val = item.Value;
    }

And as a side note (not sure if helpful), you can get the types of the arguments like this:

Type[] genericArguments = instance.GetType().GetGenericArguments();

Upvotes: 8

Jeremy Todd
Jeremy Todd

Reputation: 3289

For a quick solution, you could just use dynamic:

Dictionary<string, int> myDictionary = new Dictionary<string, int>();

myDictionary.Add("First", 1);
myDictionary.Add("Second", 2);
myDictionary.Add("Third", 3);

dynamic dynamicDictionary = myDictionary;

foreach (var entry in dynamicDictionary)
{
  object key = entry.Key;
  object val = entry.Value;
  ...whatever...
}

Upvotes: 5

Related Questions