2016-05-22 3 views
0

У меня возникли проблемы с созданием генератора дерева выражений, который я построил.Expression Tree Expression.Call Синтаксис

В сущности, я хочу, чтобы преобразовать следующее дерево выражения:

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

Вы хотите вызвать статический метод [Enumerable.First] (https://msdn.microsoft.com/en-us/library/bb291976 (v = vs.100) .aspx) –

+0

@JohanLarsson, спасибо. Тем не менее, я не пытаюсь называть этот статический метод. Я пытаюсь вызвать метод расширения Linq Сначала с лямбдой. –

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

Это нечитаемым, убедитесь, что вы добавить модульные тесты.

+0

Вы можете получить информацию о методе более безопасным способом типа: var firstMethod = ((MethodCallExpression) ((LambdaExpression) (((Expression >) (() => default (IEnumerable ). Сначала (d => true))))). Тело). Метод; – MBoros

+0

Я грузился: D –

 Смежные вопросы

  • Нет связанных вопросов^_^