Как использовать MethodCallExpression с аргументами метода - PullRequest
0 голосов
/ 30 августа 2010

Я использую MethodCallExpression для записи вызовов методов.

public void RegisterInvocation<TSource>
              (TSource target, Expression<Action<TSource>> selector)
{
   ...
}

Иногда, когда я выполняю выражение следующим образом:

selector.Compile().Invoke();

И здесь у меня возникает странный эффект (возможно, ячто-то неправильно понимать с выражениями вызова метода).

Если я регистрирую вызов метода с обычными переменными или постоянными аргументами, методы вызываются с правильными аргументами:

string item = "sometext";
instance.RegisterInvocation<ITarget>(this, p => p.Add(item));

Но если я регистрируюПри вызове метода с аргументами переменной экземпляра метод вызывается со значениями аргументов переменной экземпляра во время выполнения, а не во время регистрации:

public class Target : ITarget
{
   string item;

   public void DoSomething()
   {
      this.item = "sometext";
      instance.RegisterInvocation<ITarget>(this, p => p.Add(this.item));

      this.item = "anothertext";
      instance.CallRegisteredInvocation();
   }

   public void Add(string item)
   {
      // "somestring" expected, but item is = "anotherstring"
   }
}

Есть ли способ вызвать выражение вызова метода с аргументами ввремя регистрации?

Ответы [ 2 ]

2 голосов
/ 30 августа 2010

Причина, по которой вы видите это поведение, заключается в том, что лямбда-выражение

p => p.Add(this.item)

«захватывает» поле item (а не его значение).Когда дерево выражений скомпилировано в лямбду, оно все равно будет содержать ссылку на это поле, а не на значение, которое оно имело в то время.Если вы хотите убедиться, что у вас есть значение на момент регистрации, вы можете сделать копию этого значения:

public void DoSomething()
{
    this.item = "sometext";
    var itemCopy = item;
    instance.RegisterInvocation<ITarget>(this, p => p.Add(itemCopy));

    this.item = "anothertext";
    instance.CallRegisteredInvocation();
}
0 голосов
/ 30 августа 2010

Это потому, что вы изменили захваченную переменную (item).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...