Я недавно столкнулся с поведением, которое я не понимаю. У меня есть локальная функция, которая захватывает переменные / параметры из метода вложения. В этом случае мне кажется, что каждый раз, когда я вызываю включающий метод, будет создаваться новый «экземпляр» локальной функции. Это поведение легко увидеть в приведенном ниже коде.
Можете ли вы объяснить мне, почему локальная функция ведет себя так?
Ни VS, ни Resharper не дают мне никаких предупреждений за это, но это легко пропустить и может привести к трудностям поиска ошибок.
public class LocalFunctionTest
{
public static void Main(string[] args)
{
var localFunctionTest = new LocalFunctionTest();
localFunctionTest.UnsubscribeSubscribe(1);
localFunctionTest.UnsubscribeSubscribe(10);
localFunctionTest.UnsubscribeSubscribe(100);
Console.WriteLine(localFunctionTest.EventWithoutClosure?.GetInvocationList().Length ?? 0); //1
Console.WriteLine(localFunctionTest.EventWithClosure?.GetInvocationList().Length ?? 0); //3
}
private void UnsubscribeSubscribe(int someParam)
{
void EventHandlerWithoutClosure(object sender, EventArgs args)
{
}
//Local function that captures a variable/parameter
void EventHandlerWithClosure(object sender, EventArgs args)
{
someParam++;
}
//Using local functions as event handlers
EventWithoutClosure -= EventHandlerWithoutClosure;
EventWithoutClosure += EventHandlerWithoutClosure;
EventWithClosure -= EventHandlerWithClosure;
EventWithClosure += EventHandlerWithClosure;
}
private event EventHandler EventWithoutClosure;
private event EventHandler EventWithClosure;
}
Некоторые альтернативы приведенному выше коду:
Если вы создаете локальную переменную внутри локальная функция и присвоение ей параметра все еще ведет себя как замыкание.
Если вы создаете поле и присваиваете ему параметр в методе включения, и получаете доступ к полю в локальная функция, она не будет вести себя как замыкание.