2010-10-05 3 views
4

я следующий код:Делегаты и переменные сферы применения

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) 

У меня есть много функции, которые выглядят так, и которые могут быть вызваны одновременно.

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

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

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

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

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

Майк

+1

Я смущен, вы говорите, что ExecuteOnActiveClients вызывается с ** последним ** значением имени, а не значением во время вызова, тогда вы говорите о желании значения имени во время объявления не текущего стоимость. Можете ли вы перечитать, переформулировать свой вопрос, чтобы устранить двусмысленность, ура. – Lazarus

ответ

4

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

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

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

+0

Вот что я подумал ... Тогда мне придется это сделать. Благодаря! – Mike

2

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

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