C# Casting of Dictionary
I have this function:
void WriteMap(object value)
{
IDictionary<string, obj开发者_如何学Cect> vv = (IDictionary<string, object>)value;
foreach (KeyValuePair<string, object> obj in vv)
{
(write key)
(write value)
}
}
It works if value is really of type IDictionary<string, object>
, but it could be anything like:
IDictionary<string, int>
IDictionary<string, MyClass>
IDictionary<string, string[]>
etc.
The cast throws a run-time exception. The function does not modify the container, it only prints the keys and values. Any ideas on how I can make this work? Any help would be greatly appreciated.
Thanks!
Add a generic type parameter to your method corresponding to the type of the values in your dictionary:
void WriteMap<T>(IDictionary<string, T> dict)
{
foreach (KeyValuePair<string, T> in dict)
{
// write key
// write value
}
}
This has the advantage of eliminating the cast. If you need to pass the dictionary in as an object for some reason, just cast it to IDictionary
.
Cast it to the non-generic IDictionary
:
IDictionary vv = (IDictionary)value;
foreach (var key in vv.Keys)
{
var value = vv[key];
}
First off, why does your function receive object
as a parameter and then tries to cast it to IDictionary
? This is extremely bad practice because the calling code has no idea that the value is to be casted.
If you only want the function to work with IDictionary
'es (no late binding magic and stuff), state it explicitly. This is probably the place where you hit the wall: you need it to accept any IDictionary
, right? Perhaps this was the reason you tried to use object
and casting.
You should declare your method generic instead:
void WriteMap<TKey, TValue>(IDictionary<TKey, TValue> dict)
{
foreach (var kv in dict) // kv is KeyValuePair<TKey, TValue>
{
// (write key)
// (write value)
}
}
You can even enforce some conditions on TKey
and TValue
if you want to, see where
type constraints.
In your case, it seems like key is always a string
so you can introduce a generic parameter only for value:
void WriteMap<TValue>(IDictionary<string, TValue> dict)
{
foreach (var kv in dict) // kv is KeyValuePair<string, TValue>
{
// (write key)
// (write value)
}
}
One disadvantage of this method is that the compiler must be able to infer TValue
type during compilation time. If it is not known, or the value types might be different, it might make sense to use non-generic IDictionary
instead:
void WriteMap(IDictionary dict)
{
foreach (var kv in dict) // kv is DictionaryEntry
{
// (write key)
// (write value)
}
}
Note that in this case key is not restricted to be string
.
If you just want to print out the values, you could use the non-generic IDictionary interface:
void WriteMap(object value)
{
IDictionary vv = (IDictionary)value;
foreach (DictionaryEntry de in vv)
{
object key = de.Key;
object value = de.Value;
(write key)
(write value)
}
}
精彩评论