表达式Tree.Call语法

时间:2016-05-22 15:14:21

标签: c# expression-trees

我在旋转我构建的表达式树生成器时遇到了一些麻烦。

本质上,我想将以下内容转换为表达式树:

var res = myObjInstance.AnalysisResponseMeasures
           .First(p => p.MeasureTypeId == 1).MeasureValue

到目前为止,我已经:

var propertyExp =  Expression.Property(pe, "AnalysisResponseMeasures");
            var someParam = Expression.Parameter(typeof(AnalysisResponseMeasure), "p");
            var someParam2 = Expression.Parameter(typeof(AnalysisResponseMeasure), "p");
            var childPropExp = Expression.Equal(
                     Expression.Property(someParam, "MeasureTypeId"),
                     Expression.Constant(1));

            var firstExp = Expression.Call(
            typeof(IEnumerable<AnalysisResponseMeasure>),
            "First",
            new[] { typeof(AnalysisResponseMeasure) },
            propertyExp,
            Expression.Lambda(childPropExp, someParam2));

            var selectExp = Expression.Property(firstExp, "MeasureValue");

但是,我收到运行时错误,指出IEnumerable<AnalysisResponseMeasure>的类型没有方法First

我的参数显然是错误的,但我似乎无法弄清楚错误是什么。任何帮助都将非常感激。

1 个答案:

答案 0 :(得分:1)

玩了一下,也许这适合你:

var p = Expression.Parameter(typeof(AnalysisResponseMeasure), "p");
var prediacte = Expression.Lambda<Func<AnalysisResponseMeasure, bool>>(Expression.Equal(Expression.Property(p, "MeasureTypeId"), Expression.Constant(1)), p);

var firstMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public)
                                    .Single(m => m.Name == "First" &&
                                                 m.GetParameters().Length == 2 &&
                                                 m.GetParameters()[1].ParameterType.IsGenericType &&
                                                 m.GetParameters()[1].ParameterType.GetGenericTypeDefinition() == typeof(Func<,>))
                                    .MakeGenericMethod(typeof(AnalysisResponseMeasure));
var foo = Expression.Parameter(typeof(Foo), "foo");
var first = Expression.Call(firstMethod, Expression.Property(foo, "AnalysisResponseMeasures"), prediacte);
var measureValue = Expression.Property(first, "MeasureValue");
var yourExpression = Expression.Lambda<Func<Foo, double>>(measureValue, foo);

这是不可读的,请确保添加单元测试。