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.