Как использовать MethodCallExpression.Update - PullRequest
2 голосов
/ 15 февраля 2012

Я пытаюсь и не могу использовать ExpressionVisitor для изменения выражения, вызывающего метод.У меня есть SearchService, который инкапсулирует логику поиска и хочу иметь возможность изменять переданные аргументы поиска.

Класс, в котором следует изменить SearchFunc и запустить:

  public class SearchService
  {
    public Expression<Func<string, string, List<int>>> SearchFunc { get; set; }

    public void Run()
    {
      SearchModifier modifier = new SearchModifier();
      Expression<Func<string, string, List<int>>> newFunc = (Expression<Func<string, string, List<int>>>)modifier.Modify(SearchFunc);
    }
  }

SearchModifierопределяется как:

      public class SearchModifier : ExpressionVisitor
  {
    public Expression Modify(Expression expression)
    {
      return Visit(expression);
    }

    protected override Expression VisitMethodCall(MethodCallExpression node)
    {
      Debug.Print(string.Format("VisitMethodCall: {0}", node.ToString()));
      //VisitMethodCall: value(ExpressionTree_test.MainWindow)._adminRepository.SearchUsers("orig val", "orig val2")

      //trying to use the Update method to create an amended MethodCallExpression
      List<ConstantExpression> newargs = new List<ConstantExpression>();      
      newargs.Add(Expression.Constant("my new arg 1", typeof(string)));
      newargs.Add(Expression.Constant("my new arg 2", typeof(string)));

      MethodCallExpression methodCallExpression = node.Update(node, newargs);
      //causes exception
      //Method 'System.Collections.Generic.List`1[System.Int32] SearchUsers(System.String, System.String)' declared 
      //on type 'ExpressionTree_test.AdminRepository' cannot be called 
      //with instance of type 'System.Collections.Generic.List`1[System.Int32]'

      Debug.Print(string.Format("Amended VisitMethodCall: {0}", methodCallExpression.ToString()));

      return base.VisitMethodCall(node);
    }

Метод Run вызывается так:

_searchService = new SearchService();
      _searchService.SearchFunc = (t, s) => _adminRepository.SearchUsers("orig val", "orig val2");

Я не могу найти много информации об использовании метода MethodCallExpression.Update, поэтому не уверен, что яделаю это правильно.Как мне изменить значения аргументов в методе?Конечно, может быть лучший способ сделать это, и любые предложения с благодарностью приняты ...

1 Ответ

3 голосов
/ 15 февраля 2012

Вы не используете результат метода Update.Вы должны передать его base.VisitMethodCall вместо node:

return base.VisitMethodCall(methodCallExpression);

EDIT

Извините, я неправильно прочитал вопрос ... Первый аргумент в Update непосещаемый узел выражения, это экземпляр, в котором вызывается метод.Таким образом, код должен быть:

node.Update(node.Object, newargs);
...