Можно ли отписаться анонимным методом от события?
Если я подпишусь на такое событие:
void MyMethod()
{
Console.WriteLine("I did it!");
}
MyEvent += MyMethod;
Я могу отменить подписку, как это:
MyEvent -= MyMethod;
Но если я подпишусь, используя анонимный метод:
MyEvent += delegate(){Console.WriteLine("I did it!");};
Можно ли отписаться от этого анонимного метода? Если да, то как?
Ответы:
Просто держите ссылку на делегата.
источник
Одним из методов является объявление переменной для хранения анонимного метода, который затем будет доступен внутри самого анонимного метода. Это сработало для меня, потому что желаемое поведение было отписаться после обработки события.
Пример:
источник
Исходя из памяти, спецификация явно не гарантирует поведения в любом случае, когда речь идет об эквивалентности делегатов, созданных анонимными методами.
Если вам нужно отменить подписку, вы должны либо использовать «обычный» метод, либо оставить делегат где-то еще, чтобы вы могли отписаться точно таким же делегатом, который вы использовали для подписки.
источник
В 3.0 можно сократить до:
источник
Поскольку C # 7.0 локальных функций функции была отпущена, подход предложил на J с становится очень аккуратным.
Так что, честно говоря, у вас нет анонимной функции в качестве переменной здесь. Но я полагаю, что мотивация использовать его в вашем случае может быть применена к локальным функциям.
источник
Вместо того, чтобы хранить ссылку на любой делегат, вы можете использовать свой класс, чтобы вернуть список вызовов события вызывающей стороне. По сути, вы можете написать что-то вроде этого (при условии, что MyEvent объявлен внутри MyClass):
Таким образом, вы можете получить доступ ко всему списку вызовов извне MyClass и отписаться от любого обработчика, который вы хотите. Например:
Я написал полный пост об этой технике здесь .
источник
Вид отстойного подхода:
Это может не сработать или быть наиболее эффективным методом, но должно выполнить работу.
источник
Если вы хотите иметь возможность контролировать отписку, вам нужно идти по маршруту, указанному в принятом ответе. Однако, если вы просто заинтересованы в очистке ссылок, когда ваш подписывающийся класс выходит из области видимости, то есть другое (немного запутанное) решение, которое включает использование слабых ссылок. Я только что опубликовал вопрос и ответ по этой теме.
источник
Одно простое решение:
просто передайте переменную EventHandle в качестве параметра для себя. Событие, если у вас есть случай, когда вы не можете получить доступ к первоначально созданной переменной из-за многопоточности, вы можете использовать это:
источник
MyEvent -= myEventHandlerInstance;
? Если это возможно, у вас будет ошибка. Но я не уверен, что это так.если вы хотите обратиться к какому-либо объекту с этим делегатом, возможно, вы можете использовать Delegate.CreateDelegate (Type, Object target, MethodInfo methodInfo) .net считают, что делегат равен по target и methodInfo
источник
Если лучший способ - сохранить ссылку на подписанный eventHandler, это можно сделать с помощью словаря.
В этом примере я должен использовать анонимный метод, чтобы включить параметр mergeColumn для набора DataGridViews.
Использование метода MergeColumn с параметром enable, для которого установлено значение true, включает событие, а использование с параметром false отключает его.
источник