How to convert object to Dictionary<TKey, TValue> in C#?
C#.NetObjectDictionaryC# Problem Overview
How do I convert a dynamic object to a Dictionary<TKey, TValue>
in C# What can I do?
public static void MyMethod(object obj)
{
if (typeof(IDictionary).IsAssignableFrom(obj.GetType()))
{
// My object is a dictionary, casting the object:
// (Dictionary<string, string>) obj;
// causes error ...
}
else
{
// My object is not a dictionary
}
}
C# Solutions
Solution 1 - C#
The above answers are all cool. I found it easy to json serialize the object and deserialize as a dictionary.
var json = JsonConvert.SerializeObject(obj);
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
I don't know how performance is effected but this is much easier to read. You could also wrap it inside a function.
public static Dictionary<string, TValue> ToDictionary<TValue>(object obj)
{
var json = JsonConvert.SerializeObject(obj);
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, TValue>>(json);
return dictionary;
}
Use like so:
var obj = new { foo = 12345, boo = true };
var dictionary = ToDictionary<string>(obj);
Solution 2 - C#
I use this helper:
public static class ObjectToDictionaryHelper
{
public static IDictionary<string, object> ToDictionary(this object source)
{
return source.ToDictionary<object>();
}
public static IDictionary<string, T> ToDictionary<T>(this object source)
{
if (source == null)
ThrowExceptionWhenSourceArgumentIsNull();
var dictionary = new Dictionary<string, T>();
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(source))
AddPropertyToDictionary<T>(property, source, dictionary);
return dictionary;
}
private static void AddPropertyToDictionary<T>(PropertyDescriptor property, object source, Dictionary<string, T> dictionary)
{
object value = property.GetValue(source);
if (IsOfType<T>(value))
dictionary.Add(property.Name, (T)value);
}
private static bool IsOfType<T>(object value)
{
return value is T;
}
private static void ThrowExceptionWhenSourceArgumentIsNull()
{
throw new ArgumentNullException("source", "Unable to convert object to a dictionary. The source object is null.");
}
}
the usage is just to call .ToDictionary()
on an object
Hope it helps.
Solution 3 - C#
public static KeyValuePair<object, object > Cast<K, V>(this KeyValuePair<K, V> kvp)
{
return new KeyValuePair<object, object>(kvp.Key, kvp.Value);
}
public static KeyValuePair<T, V> CastFrom<T, V>(Object obj)
{
return (KeyValuePair<T, V>) obj;
}
public static KeyValuePair<object , object > CastFrom(Object obj)
{
var type = obj.GetType();
if (type.IsGenericType)
{
if (type == typeof (KeyValuePair<,>))
{
var key = type.GetProperty("Key");
var value = type.GetProperty("Value");
var keyObj = key.GetValue(obj, null);
var valueObj = value.GetValue(obj, null);
return new KeyValuePair<object, object>(keyObj, valueObj);
}
}
throw new ArgumentException(" ### -> public static KeyValuePair<object , object > CastFrom(Object obj) : Error : obj argument must be KeyValuePair<,>");
}
From the OP:
> Instead of converting my whole Dictionary, i decided to keep my obj > dynamic the whole time. When i access the keys and values of my > Dictionary with a foreach later, i use foreach(dynamic key in > obj.Keys) and convert the keys and values to strings simply.
Solution 4 - C#
Another option is to use NewtonSoft.JSON.
var dictionary = JObject.FromObject(anObject).ToObject<Dictionary<string, object>>();
Solution 5 - C#
If you mind to use LINQ Expression;
public static Dictionary<string, object> ConvertFromObjectToDictionary(object arg)
{
return arg.GetType().GetProperties().ToDictionary(property => property.Name, property => property.GetValue(arg));
}
Solution 6 - C#
this should work:
for numbers, strings, date, etc.:
public static void MyMethod(object obj)
{
if (typeof(IDictionary).IsAssignableFrom(obj.GetType()))
{
IDictionary idict = (IDictionary)obj;
Dictionary<string, string> newDict = new Dictionary<string, string>();
foreach (object key in idict.Keys)
{
newDict.Add(key.ToString(), idict[key].ToString());
}
}
else
{
// My object is not a dictionary
}
}
if your dictionary also contains some other objects:
public static void MyMethod(object obj)
{
if (typeof(IDictionary).IsAssignableFrom(obj.GetType()))
{
IDictionary idict = (IDictionary)obj;
Dictionary<string, string> newDict = new Dictionary<string, string>();
foreach (object key in idict.Keys)
{
newDict.Add(objToString(key), objToString(idict[key]));
}
}
else
{
// My object is not a dictionary
}
}
private static string objToString(object obj)
{
string str = "";
if (obj.GetType().FullName == "System.String")
{
str = (string)obj;
}
else if (obj.GetType().FullName == "test.Testclass")
{
TestClass c = (TestClass)obj;
str = c.Info;
}
return str;
}
Solution 7 - C#
Assuming key can only be a string but value can be anything try this
public static Dictionary<TKey, TValue> MyMethod<TKey, TValue>(object obj)
{
if (obj is Dictionary<TKey, TValue> stringDictionary)
{
return stringDictionary;
}
if (obj is IDictionary baseDictionary)
{
var dictionary = new Dictionary<TKey, TValue>();
foreach (DictionaryEntry keyValue in baseDictionary)
{
if (!(keyValue.Value is TValue))
{
// value is not TKey. perhaps throw an exception
return null;
}
if (!(keyValue.Key is TKey))
{
// value is not TValue. perhaps throw an exception
return null;
}
dictionary.Add((TKey)keyValue.Key, (TValue)keyValue.Value);
}
return dictionary;
}
// object is not a dictionary. perhaps throw an exception
return null;
}
Solution 8 - C#
public static void MyMethod(object obj){
Dictionary<string, string> dicEditdata = data as Dictionary<string, string>;
string abc=dicEditdata["id"].ToString();}
suppose---
if you place the cursor over the object(obj) while debugging and
if you get an object with the value {['id':'ID1003']}
then you can use the value as
string abc=dicEditdata["id"].ToString();
Solution 9 - C#
I've done something like this and works for me.
> using System.ComponentModel;
var dictionary = new Dictionary<string, string>();
foreach (var propDesc in TypeDescriptor.GetProperties(Obj))
{
if (!string.IsNullOrEmpty(propDesc.GetValue(Obj)))
{
dictionary.Add(propDesc.Name, propDesc.GetValue(Obj));
}
}
Also, another alternative and innovative solution is here.
var dictionary = new System.Web.Routing.RouteValueDictionary(Obj);
Solution 10 - C#
This code securely works to convert Object to Dictionary (having as premise that the source object comes from a Dictionary):
private static Dictionary<TKey, TValue> ObjectToDictionary<TKey, TValue>(object source)
{
Dictionary<TKey, TValue> result = new Dictionary<TKey, TValue>();
TKey[] keys = { };
TValue[] values = { };
bool outLoopingKeys = false, outLoopingValues = false;
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(source))
{
object value = property.GetValue(source);
if (value is Dictionary<TKey, TValue>.KeyCollection)
{
keys = ((Dictionary<TKey, TValue>.KeyCollection)value).ToArray();
outLoopingKeys = true;
}
if (value is Dictionary<TKey, TValue>.ValueCollection)
{
values = ((Dictionary<TKey, TValue>.ValueCollection)value).ToArray();
outLoopingValues = true;
}
if(outLoopingKeys & outLoopingValues)
{
break;
}
}
for (int i = 0; i < keys.Length; i++)
{
result.Add(keys[i], values[i]);
}
return result;
}
Solution 11 - C#
This way for object array to Dictionary
object[] a = new object[2];
var x = a.Select(f => (Dictionary<string, object>)f).ToList();
This way for single object to Dictionary
object a = new object;
var x = (Dictionary<string, object>)a;
Solution 12 - C#
I hope this could work :)
// obj = new { a = "string", b = 0, c = true };
static Dictionary<string, object> ToDictionary(object obj)
{
int i = 0;
var props = obj.GetType().GetProperties();
return props.ToDictionary(k => props[i].Name, v => props[i++].GetValue(obj));
}
Solution 13 - C#
You can create a generic extension method and then use it on the object like:
public static class Extensions
{
public static KeyValuePair<TKey, TValue> ToKeyValuePair<TKey, TValue>(this Object obj)
{
// if obj is null throws exception
Contract.Requires(obj != null);
// gets the type of the obj parameter
var type = obj.GetType();
// checks if obj is of type KeyValuePair
if (type.IsGenericType && type == typeof(KeyValuePair<TKey, TValue>))
{
return new KeyValuePair<TKey, TValue>(
(TKey)type.GetProperty("Key").GetValue(obj, null),
(TValue)type.GetProperty("Value").GetValue(obj, null)
);
}
// if obj type does not match KeyValuePair throw exception
throw new ArgumentException($"obj argument must be of type KeyValuePair<{typeof(TKey).FullName},{typeof(TValue).FullName}>");
}
and usage would be like:
KeyValuePair<string,long> kvp = obj.ToKeyValuePair<string,long>();
Solution 14 - C#
I use this simple method:
public Dictionary<string, string> objToDict(XYZ.ObjectCollection objs) {
var dict = new Dictionary<string, string>();
foreach (KeyValuePair<string, string> each in objs){
dict.Add(each.Key, each.Value);
}
return dict;
}
Solution 15 - C#
You can use this:
Dictionary<object,object> mydic = ((IEnumerable)obj).Cast<object>().ToList().ToDictionary(px => px.GetType().GetProperty("Key").GetValue(px), pv => pv.GetType().GetProperty("Value").GetValue(pv));
Solution 16 - C#
As I understand it, you're not sure what the keys and values are, but you want to convert them into strings?
Maybe this can work:
public static void MyMethod(object obj)
{
var iDict = obj as IDictionary;
if (iDict != null)
{
var dictStrStr = iDict.Cast<DictionaryEntry>()
.ToDictionary(de => de.Key.ToString(), de => de.Value.ToString());
// use your dictStrStr
}
else
{
// My object is not an IDictionary
}
}
Solution 17 - C#
object parsedData = se.Deserialize(reader);
System.Collections.IEnumerable stksEnum = parsedData as System.Collections.IEnumerable;
then will be able to enumerate it!
Solution 18 - C#
Simple way:
public IDictionary<T, V> toDictionary<T, V>(Object objAttached)
{
var dicCurrent = new Dictionary<T, V>();
foreach (DictionaryEntry dicData in (objAttached as IDictionary))
{
dicCurrent.Add((T)dicData.Key, (V)dicData.Value);
}
return dicCurrent;
}