Home > Mobile >  Converting Dictionary<string, dynamic> to Dictionary<string, string>
Converting Dictionary<string, dynamic> to Dictionary<string, string>

Time:03-01

I'm pretty new to C#. Currently I am working on some code left behind by someone else and it might have never worked before. There is a method that accepts two string values as parameters.

public void Update(string area, string value)
{
   //Perform operation
}

The above method was being called like this and this result in - "The best overloaded method match for..." error being thrown. The dynamic values can consist of bool, int and string.

public void UpdateAll(Dictionary<string, dynamic> values)
      {
         foreach (var entry in values)
         {
            Update(entry.Key, entry.Value);
         }
      }

My solution was to convert the Dictionary<string, dynamic> to Dictionary<string, string> within UpdateAll method first as shown below as I thought it will require the least amount of change. However I'm getting the error "Cannot convert type 'int' to 'string'" or "Cannot convert type 'bool' to 'string'"

public void UpdateAll(Dictionary<string, dynamic> values)
      {
         var convertedValues = values.ToDictionary(row => (string) row.Key, row => (string) row.Value);
         foreach (var entry in convertedValues)
         {
            Update(entry.Key, entry.Value);
         }
      }

What would be the best way to resolve and go about it?

CodePudding user response:

Just do this

        Update(entry.Key, entry.Value.ToString());

Be wary of interesting types that don't create an expected representation for ToString(). (eg classes will often just give you a hash value.)

If you just have base types you should be fine.

CodePudding user response:

The problem here is that dynamic can be any type at runtime and you (and compiler) don't know the actual type until runtime. See this

var values = new Dictionary<string, dynamic>();
values.Add("key1", 5);
values.Add("key2", true);
values.Add("key3", "value");

That code is compiled and executed nicely. The dictionary behaves similarly as this has object as its type argument for values.

Therefore when you iterate this dictionary, entry.Value might have different types for different elements of dictionary: int, bool, string, whatever. And when this has, for example, type int, the overload resolution process just can't find the method Update(string, int), therefore the exception occurs. You can fix this by simply converting it to string with a simple call ToString(). Hopefully all the types in .NET have ToString method, therefore it's pretty safe:

Update(entry.Key, entry.Value.ToString())

But be careful, entry.Value still can be null, so that it might be useful first to check against null and then convert it to string.

Another way of fixing this is to have overloads of Update method for different types which can be part of your dictionary. This is not very feasible if you don't really know what the dictionary might contain, but might be pretty good if you know the types for sure and they won't be extended too often. And of course if this is possible to write different versions of the Update method:

void Update(string area, string value) { ... }
void Update(string area, int value) { ... }
void Update(string area, bool value) { ... }

Also, I don't know your client code which calls UpdateAll, but you can also consider this dictionary to have an object type argument instead of dynamic. The behavior will be the same, but in the case of object you have a help from the compiler about ToString method.

void UpdateAll(Dictionary<string, object> values)

Note that this way of declaring the dictionary (with object) doesn't allow using the method overloads described above.

  • Related