Reputation: 81
I am stuck at the following problem:
I have a class like
public class DataItem
{
public decimal? ValueA{ get; set; }
public decimal? ValueB { get; set; }
public decimal? valueC { get; set; }
...
}
and would like to have something like
var keySelectors = new Dictionary<string, Func<DataItem, decimal?>>
{
{"ValueA", x => x.ValueA},
{"ValueB", x => x.ValueB},
{"ValueC", x => x.ValueC},
...
}.ToList();
to be used for a user defined analysis, but I need a more generic way to create it.
So I tried the following:
var keySelectors= typeof(DataItem).GetProperties()
.Select(x => new KeyValuePair<string, Func<DataItem, decimal?>>(x.Name, x.DoNotKnow));
the DoNotKnow is the point where I am lost.
Or is this a wrong approach for the desired result to enable the user to choose the data on which his analysis is based?
Upvotes: 0
Views: 201
Reputation: 1557
A human readable solution:
Func<DataItem, decimal?> GetValue(PropertyInfo p) => (item) => (decimal?)(p.GetValue(item));
var keySelctors = typeof(DataItem).GetProperties().ToDictionary(p => p.Name, GetValue);
Upvotes: 0
Reputation: 40788
What you want to do is create a delegate to an instance method, the property's getter method. This can be done with CreateDelegate:
var props = typeof(DataItem).GetProperties()
.Select(x => new KeyValuePair<string, Func<DataItem, decimal?>>(x.Name,
(Func<DataItem, decimal?>)x.GetGetMethod().CreateDelegate(typeof(Func<DataItem, decimal?>))));
Invoking a delegate is faster than doing this using the reflection-based method, GetValue on PropertyInfo, but obviously the impact depends on your scenario.
Upvotes: 2
Reputation: 535
Here's one way:
typeof(DataItem).GetProperties()
.Select(p => new KeyValuePair<string, Func<DataItem, decimal?>>(
p.Name,
item => (decimal?)typeof(DataItem).InvokeMember(p.Name, BindingFlags.GetProperty, null, item, null)
));
Upvotes: 0