简体   繁体   English

获取功能 <T1, T2> 来自PropertyInfo

[英]Get Func<T1, T2> from PropertyInfo

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. DoNotKnow是我迷路的地方。

Or is this a wrong approach for the desired result to enable the user to choose the data on which his analysis is based? 还是对于期望的结果使用户能够选择其分析所基于的数据的错误方法?

What you want to do is create a delegate to an instance method, the property's getter method. 您要做的是创建一个实例方法的委托,该实例方法是属性的getter方法。 This can be done with CreateDelegate: 这可以通过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. 调用委托要比在PropertyInfo上使用基于反射的方法GetValue更快,但是显然影响取决于您的方案。

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)
    ));

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM