Добавление и удаление анонимного обработчика событий

Я задавался вопросом, работало ли это на самом деле?

private void RegisterKeyChanged(T item) 
{
    item.OnKeyChanged += (o, k) => ChangeItemKey((T)o, k);
}

private void UnRegisterKeyChanged(T item) 
{
    item.OnKeyChanged -= (o, k) => ChangeItemKey((T)o, k);
}

Как компилятор знает, что обработчики событий являются тем же? Это даже рекомендуется?

54
задан John Saunders 26 March 2014 в 08:10
поделиться

5 ответов

Там есть страница MSDN, которая говорит об этом:

Как подписаться на и отписаться от мероприятий

В частности:

Если вам не придется отписаться от [SIC] событие позже вы можете использовать оператор присваивания дополнения (+ =) для прикрепить анонимный метод мероприятие.

А также:

важно отметить, что вы не может легко отписаться от событие, если вы использовали анонимный Функция подписаться на это. К Отписаться в этот сценарий, это необходимо вернуться к коду, где Вы подписываетесь на мероприятие, храните анонимный метод в делегате переменная, а затем добавьте делегат на событие . В общем, мы рекомендуем что вы не используете анонимные функции, чтобы подписаться на события, если вам придется отписаться от событие в более позднем моменте в вашем код.

60
ответ дан 7 November 2019 в 08:03
поделиться
121 --- 1106224-

Если вам нужно отказаться от подписки обработчика событий, вам необходимо иметь определенную ссылку на конкретный делегат. Глядя на делегат. Неизмещение Вы обнаружите, что делегаты не просто сравниваются с использованием справедливого равенства, однако это не имеет значения для анонимных делегатов.

Для анонимного делегата компилятор (в основном) только создает новый «неанонимный» делегат для каждого анонимного делегата, даже если органы делегата одинаковы. Из-за этого каркас не найдет делегата для отписания, когда вы используете пример кода, который вы дали.

6
ответ дан 7 November 2019 в 08:03
поделиться

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

2
ответ дан 7 November 2019 в 08:03
поделиться

Если вы проверяете документ для делегата. Образность, вы обнаружите, что не сравниваются со ссылкой.

1
ответ дан 7 November 2019 в 08:03
поделиться

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

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

3
ответ дан 7 November 2019 в 08:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: