I'm using an API that returns a key-value collection as a Dictionary<string, string>
. I need to convert that to a Dictionary<string, object>
. I have a sense that there should be a way to do this conversion/mapping without "manually" looping through each key-value pair, but Googling or the C# object reference didn't immediately yield a solution.
views:
312answers:
3
+2
Q:
What is the leanest way to convert a Dictionary<string, string> to a Dictionary<string, object>?
+5
A:
Try the following
var newMap = oldMap.ToDictionary(pair => pair.Key, pair=>(object)pair.Value);
JaredPar
2010-02-02 23:08:03
+1, however worth noting that this is not any "leaner" than the way the OP wants to avoid - it just hides it behind a pretty shiny syntax.
Rex M
2010-02-02 23:14:02
@Rex, true, but it avoids the manual loop as asked for by the OP.
JaredPar
2010-02-02 23:17:20
"Lean" can be stretched to mean different things. In my case I was just looking for a quick solution to save the day. Thanks for this answer.
Ates Goral
2010-02-03 00:46:20
A:
You can use this extension method:
public static class ObjectExtensions
{
public static object GetPropertyValue(this object obj, string property)
{
return TypeDescriptor.GetProperties(obj)[property].GetValue(obj);
}
public static IDictionary<string, object> ToDictionary(this object obj)
{
IDictionary<string, object> result = new Dictionary<string, object>();
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(obj);
foreach (PropertyDescriptor property in properties)
{
result.Add(property.Name, property.GetValue(obj));
}
return result;
}
}
You use it like:
new Dictionary<string, string>().ToDictionary();
Mendy
2010-02-02 23:09:11
+1
A:
No looping, maps a Dictionary{T, U}
to Dictionary{T, object}
in constant time:
class DictionaryWrapper<T, U> : IDictionary<T, object>
{
readonly Dictionary<T, U> inner;
public DictionaryWrapper(Dictionary<T, U> wrapped)
{
this.inner = wrapped;
}
#region IDictionary<T,object> Members
public void Add(T key, object value) { inner.Add(key, (U)value); }
public bool ContainsKey(T key) { return inner.ContainsKey(key); }
public ICollection<T> Keys { get { return inner.Keys; } }
public bool Remove(T key) { return inner.Remove(key); }
public bool TryGetValue(T key, out object value)
{
U temp;
bool res = inner.TryGetValue(key, out temp);
value = temp;
return res;
}
public ICollection<object> Values { get { return inner.Values.Select(x => (object)x).ToArray(); } }
public object this[T key]
{
get { return inner[key]; }
set { inner[key] = (U)value; }
}
#endregion
#region ICollection<KeyValuePair<T,object>> Members
public void Add(KeyValuePair<T, object> item) { inner.Add(item.Key, (U)item.Value); }
public void Clear() { inner.Clear(); }
public bool Contains(KeyValuePair<T, object> item) { return inner.Contains(new KeyValuePair<T, U>(item.Key, (U)item.Value)); }
public void CopyTo(KeyValuePair<T, object>[] array, int arrayIndex) { throw new NotImplementedException(); }
public int Count { get { return inner.Count; } }
public bool IsReadOnly { get { return false; } }
public bool Remove(KeyValuePair<T, object> item) { return inner.Remove(item.Key); }
#endregion
#region IEnumerable<KeyValuePair<T,object>> Members
public IEnumerator<KeyValuePair<T, object>> GetEnumerator()
{
foreach (var item in inner)
{
yield return new KeyValuePair<T, object>(item.Key, item.Value);
}
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
foreach (var item in inner)
{
yield return new KeyValuePair<T, object>(item.Key, item.Value);
}
}
#endregion
}
With a few more generic params, you can generalize this class further so that it maps a Dictionary{A, B}
to a Dictionary{C, D}
.
Juliet
2010-02-02 23:42:19