C#我在寻找Lambda / Expression / Func / Reflection进行运行时属性替换的构造是什么?

时间:2011-09-30 10:21:45

标签: c# lambda expression

我在泛型基类上有一个方法,我想为它的所有超类执行

逻辑如下:

BuildAverageDateStats(List<type> items, DateProperty1 exp, DateProperty2 exp2)
{
 return new Stat{ 
  Value = items.Average(c => (c.DateProperty2 - c.DateProperty1).Milliseconds)
 };
}

myobject.BuildAverageDateStats(list, () => c.QueuedDate, () => c.CompletedDate);
myobject.BuildAverageDateStats(list, () => c.ActionedDate, () => c.CompletedDate);

我想我需要表达,但不确定如何......

我可以将其作为Func发送,即Value = items.Average(c => myfunc(c)),但寻找属性替换示例。

3 个答案:

答案 0 :(得分:2)

Stat BuildAverageDateStats<U>(List<type> items, Func<U, double> exp)
where U:type
{
 return new Stat{ 
  Value = items.OfType<U>().Average(exp);
 };
}

你可以这样称呼它

BuidlAverageDateStats<Dog>(items, d=>d.Age - d.Height);

虽然我的例子没有意义。

答案 1 :(得分:0)

如果您真的只使用现在拥有的三个DateTime属性之一,我会保留方法签名,就像您现在拥有它一样。 为了使事情更整洁,在类上为您的属性创建一些公共静态只读委托字段,并使用它们,而不是一次又一次地写相同的表达式:

    public static readonly DateSelector Date1Property = delegate(CompareTest c) { return c.Date1; };
    public static readonly DateSelector Date2Property = delegate(CompareTest c) { return c.Date2; };
    public static readonly DateSelector Date3Property = delegate(CompareTest c) { return c.Date3; };

另一方面,如果您希望继承类实现的属性多于现在的三个属性,则可以考虑将属性作为String传递并使用Dynamic Linq Library(并构建一个返回动态表达式的动态表达式) property)或DynamicMethod来归还你的财产。两者都会有痛苦表现的反思。如果你需要它,我会有一些代码。 虽然类型安全性不在窗外,所以除非必要,否则我不会使用它,听起来不是这样。

门诺

答案 2 :(得分:0)

static Stat BuildAverageDateStats<T>(List<T> items, string pname1, string pname2){
    return new Stat { 
        Value = items.Average( c => 
        {
            var ty = c.GetType();
            var pv1 = (dynamic)ty.GetProperty(pname1).GetValue(c,null);
            var pv2 = (dynamic)ty.GetProperty(pname2).GetValue(c,null);
            return pv2 - pv1;
        })
    };
}