C # cast Dictionary <string, AnyType> to dictionary <string, Object> (Reflection involving)
Is it possible to make a Dictionary<string, Anything>
consistent intermediate common type? So I could use <string, string>
, <string, bool>
, <string, int>
, <string, anything>
all for the same type of dictionary?
I am working on a project that uses heavy reflection, and I need to be able to handle offset types as such:
FieldInfo field = this.GetType().GetField(fieldName); Dictionary<string, Object> dict = (Dictionary<string, Object>)field.GetValue(this);
The above code is what I have, and the program always fails when passing from the field. GetValue in a general Dictionary<string, Object>
.
Is there any way to do this? Or do I just need to figure out another way to handle these dictionaries?
Any help would be greatly appreciated.
Following AakashM's answer , Cast doesn't seem to play the ball. You can get around this using a small helper method:
IDictionary dictionary = (IDictionary)field.GetValue(this); Dictionary<string, object> newDictionary = CastDict(dictionary) .ToDictionary(entry => (string)entry.Key, entry => entry.Value); private IEnumerable<DictionaryEntry> CastDict(IDictionary dictionary) { foreach (DictionaryEntry entry in dictionary) { yield return entry; } }
In this case, it is convenient to use duck print in foreach.
Even if you could find a way to express it, it would be wrong - not that Dictionary<string, bool>
a Dictionary<string, object>
, so we definitely donβt want to pour . Think that if we could distinguish, we could try to put string
as a value, which obviously does not fit!
However, we can use a non-generic IDictionary
(which is implemented by all Dictionary<,>
), and then use it to build a new Dictionary<string, object>
with the same values:
FieldInfo field = this.GetType().GetField(fieldName); IDictionary dictionary = (IDictionary)field.GetValue(this); Dictionary<string, object> newDictionary = dictionary .Cast<dynamic>() .ToDictionary(entry => (string)entry.Key, entry => entry.Value);
(note that you cannot use .Cast<DictionaryEntry>
here for the reasons discussed here . If you are before C # 4 and therefore do not have dynamic
, you will need to do the enumeration manually, as Gibsnag does the answer )
Yes You can apply FieldInfo
to a Dictionary
as shown below.
This is one example that I used in my code.
Dictionary<string, string> GetTheDict = FilesAndPaths.GetType() .GetFields() .Where(f => f.Name.Equals(pLoadFile)) .Select(f => (Dictionary<string, string>)f.GetValue(FilesAndPaths)) .Single();
Think about whether you really need to cast to and from object
. I started this journey and came across this article before I realized that I could achieve what I need, instead of generating, and not with the help of generics. For instance:
class DictionaryUtils<T> { public static T ValueOrDefault(IDictionary<string, T> dictionary, string key) { return dictionary.ContainsKey(key) ? dictionary[key] : default(T); } }
This bit of code is much cleaner and will be faster than the equivalent conversion code shown in other answers.