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.

+6
source share
5 answers

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.

+8
source

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 )

+8
source

Does this help you?

 Dictionary<a, b> output = input.ToDictionary(item => item.Key, item => (SomeType)item.Value); 
+5
source

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(); 
0
source

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.

0
source

Source: https://habr.com/ru/post/913509/


All Articles