Терминология при копировании захваченной переменной для лямбда / анонимного метода

StackOverflow https://stackoverflow.com/questions/1086243

Вопрос

Я перевел этот код (у него плохой побочный эффект в том, что он просто захватывает внешнюю переменную):

foreach (TaskPluginInfo tpi in Values)
{                    
    GenerateMenu(menuStrip, tpi.MenuTree, tpi.MenuText, delegate { tpi.ShowTask() });
}

К этому коду (поскольку приведенный выше не работает):

foreach (TaskPluginInfo tpi in Values)
{                    
    // must capture the variable
    var x = tpi;
    GenerateMenu(menuStrip, tpi.MenuTree, tpi.MenuText, delegate { x.ShowTask(); });
}

Какова правильная терминология для этого обхода этого малоизвестного побочного эффекта?На данный момент я прокомментировал "необходимо захватить переменную". Является ли слово capture правильной терминологией?

Это было полезно?

Решение

Ну, и tpi, и x являются переменными (разного рода), которые фиксируются в одном из примеров...главный момент здесь заключается в том, что вы хотите ограничить область применения захваченной переменной (в идеале x) внутрь цикла.

Так что, возможно;"захватить значение переменной итерации;не сама переменная итерации"

Другие советы

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

Как бы вы назвали утверждение, на которое вы ссылаетесь?Я думаю, что "захватывать" - хороший глагол для использования.В конце концов, пока всем ясно, что вы имеете в виду, все в порядке :-)

Предупреждение Resharper называет этот сценарий "Доступом к измененному закрытию", и рекомендуемым решением является "Захват переменной", поэтому в моем комментарии я бы сказал "Необходимо захватить переменную, чтобы избежать доступа к измененному закрытию".

Да, это захват;вы также можете использовать "закрывает поверх".Вот пара примеров предложений;

делегат, переданный в GenerateMenu, фиксирует переменную x.

делегат, переданный в GenerateMenu, представляет собой лямбда-выражение, которое закрывается поверх x .

Возможно, вы также захотите поискать в Google термины "свободная переменная" и "связанная переменная".

"присвоите переменную итерации локальной переменной, область действия которой находится внутри цикла"

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top