Область делегатов и переменных - PullRequest
4 голосов
/ 05 октября 2010

У меня есть следующий код:

public void SetMove(Position3D pos, float time, float linearity, bool relative)
{
    ExecuteOnActiveClients(delegate(NeuroClient client)
                               {
                                   client.Engine.GetProcAnimation(name).SetMove(pos, time, linearity, relative);
                               }, true, true);
}

Где ExecuteOnActiveClients помещает делегата в очередь, используется асинхронно и имеет следующую подпись:

void ExecuteOnActiveClients(ClientDelegate action, Boolean parallel, Boolean wait, Boolean lockClient)

У меня есть много функций, которые похожи на эту, и которые могут вызываться одновременно.

Я заметил, что я должен сохранить значение name (которое является приватным полем класса) в переменной в функции, прежде чем я выполню ExecuteOnActiveClients, чтобы этот код работал хорошо, потому что если я нет, делегат использует последнее значение name , а не значение, которое поле имело при вызове функции.

Полагаю, это проблема области видимости, потому что параметры функции (pos, время, линейность и относительные) верны.

Есть ли способ заставить делегата использовать значение name при его создании, а не значение name при его выполнении?

Я бы хотел избежать сохранения значения в каждой из множества функций, которые используют ExecuteOnActiveClients , если это возможно.

Заранее спасибо

Mike

Ответы [ 2 ]

4 голосов
/ 05 октября 2010

В настоящее время делегат не хранит значение name вообще.Он захватывает this, а затем использует его для разрешения this.name всякий раз, когда вы ссылаетесь на него.

Так работают анонимные методы и лямбда-выражения, и вы ничего не можете сделать, чтобы изменить их поведение:создание локальной переменной является обходным решением.(Это все еще будет захватывать эту переменную, а не ее текущее значение, но вы, вероятно, можете быть уверены, что впоследствии не измените значение локальной переменной.)

Для получения дополнительной информации и другой ловушки, в которую вы можете легко попастьЯ призываю вас прочитать сообщения в блоге Эрика Липперта на тему «Закрытие переменной цикла, считающейся вредной» ( часть 1 , часть 2 ).

2 голосов
/ 05 октября 2010

Непосредственно перед созданием вашего делегата создайте временную локальную переменную, содержащую значение имени, и используйте ее в своем делегате.

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