Я задавался вопросом, работало ли это на самом деле?
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);
}
Как компилятор знает, что обработчики событий являются тем же? Это даже рекомендуется?
Там есть страница MSDN, которая говорит об этом:
Как подписаться на и отписаться от мероприятий
В частности:
Если вам не придется отписаться от [SIC] событие позже вы можете использовать оператор присваивания дополнения (+ =) для прикрепить анонимный метод мероприятие.
А также:
важно отметить, что вы не может легко отписаться от событие, если вы использовали анонимный Функция подписаться на это. К Отписаться в этот сценарий, это необходимо вернуться к коду, где Вы подписываетесь на мероприятие, храните анонимный метод в делегате переменная, а затем добавьте делегат на событие . В общем, мы рекомендуем что вы не используете анонимные функции, чтобы подписаться на события, если вам придется отписаться от событие в более позднем моменте в вашем код.
Если вам нужно отказаться от подписки обработчика событий, вам необходимо иметь определенную ссылку на конкретный делегат. Глядя на делегат. Неизмещение
Вы обнаружите, что делегаты не просто сравниваются с использованием справедливого равенства, однако это не имеет значения для анонимных делегатов.
Для анонимного делегата компилятор (в основном) только создает новый «неанонимный» делегат для каждого анонимного делегата, даже если органы делегата одинаковы. Из-за этого каркас не найдет делегата для отписания, когда вы используете пример кода, который вы дали.
Я не верю, что это будет работать. Если вам действительно нужно отменить регистрацию от события, вы должны указать явный обработчик событий, который вы можете позже отменить регистрацию вместо анонимного делегата.
Если вы проверяете документ для делегата. Образность, вы обнаружите, что не сравниваются со ссылкой.
Боюсь, это не сработает, поскольку два объявленных вами лямбда-выражения (и делегаты) на самом деле являются разными объектами и возвращают разные ссылки. Следовательно, удаление обработчика ( - =
) всегда будет неудачным.
Обычное решение этой проблемы (когда вам нужно удалить обработчик) - просто преобразовать выражение lamba в правильный метод. Альтернативой является сохранение переменной класса для делегата обработчика событий, а также добавление и удаление ее, хотя я лично не являюсь ее поклонником. (Во всяком случае, это больше хлопот, чем просто создание обычного метода.)