Any LINQ alternative for loop in reflection?
-
31-05-2021 - |
Question
I have a type T with fields+properties that i'd like to populate from a dictionary, pref case insensitive
I can obviously do
foreach(PropertyInfo pi in t.GetProperties() )
.....
and then
foreach(FieldInfo pi in t.GetFields() )
.....
Hoping there's a better way, perhaps using LINQ ?
Solution
Here is an option,
var propDict = t.GetProperties().ToLookup<PropertyInfo, string, Action<object, object>>(
p => p.Name, p => (obj, val) => p.SetValue(obj, val, null));
var fieldDict = t.GetFields().ToLookup<FieldInfo, string, Action<object, object>>(
f => f.Name, f => (obj, val) => f.SetValue(obj, val));
var memberDict = pDict.Concat(fDict).ToDictionary(p => p.Key, p => p.Value);
...and then to use something like...
Dictionary<string, object> outDict;
foreach (var keyval in outDict)
memberDict[keyval.Key](container, keyval.Value);
...though not sure if it makes too much sense as going through properties/fields is relatively simple anyway, an idea maybe.
OTHER TIPS
I don't think there's anything better. PropertyInfo
and FieldInfo
types have different APIs for setting values, therefore you won't be able to fill their values in a uniform way even if you gather them into an IEnumerable<MemberInfo>
.
Well, you could write a wrapper that would handle both PropertyInfo
and FieldInfo
in a uniform way encapsulating the different APIs. But 2 foreach
loops are easier anyway.
Depends what are you planning to do with pi
.
If transform to some new class then you can
t.GetProperties().Select(pi => t.GetFields().Select(pi =>
If read properties and output them, then
foreach
loop is better than LINQ.