从 PropertyInfo 获取 Func<T1, T2>

Get Func<T1, T2> from PropertyInfo

我遇到了以下问题:
我有一个class喜欢

public class DataItem
{
    public decimal? ValueA{ get; set; }
    public decimal? ValueB { get; set; }
    public decimal? valueC { get; set; }
    ...
}

并希望有类似的东西

 var keySelectors = new Dictionary<string, Func<DataItem, decimal?>>
 {
     {"ValueA", x => x.ValueA},
     {"ValueB", x => x.ValueB},
     {"ValueC", x => x.ValueC},
     ...
 }.ToList();

用于用户定义的分析,但我需要一种更通用的方法来创建它。
所以我尝试了以下方法:

var keySelectors= typeof(DataItem).GetProperties()
  .Select(x => new KeyValuePair<string, Func<DataItem, decimal?>>(x.Name, x.DoNotKnow));

DoNotKnow 是我迷路的地方。

或者对于使用户能够选择他的分析所基于的数据的期望结果,这是一种错误的方法吗?

您要做的是创建一个实例方法的委托,即 属性 的 getter 方法。这可以通过 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?>))));

调用委托比使用基于反射的方法 GetValue on PropertyInfo 执行此操作更快,但显然影响取决于您的场景。

这是一种方法:

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

人类可读的解决方案:

Func<DataItem, decimal?> GetValue(PropertyInfo p) => (item) => (decimal?)(p.GetValue(item));

var keySelctors =  typeof(DataItem).GetProperties().ToDictionary(p => p.Name, GetValue);