Отмена подписки на события через анонимного делегата

Я использую анализ кода Resharper 5.1 много раз, я получаю комментарий от resharper как

"Отмена подписки на события через анонимный делегат"

#Part of Code  

if (((bool)e.NewValue))
{
    listView.PreviewTextInput += (o,args) =>
        listView_PreviewTextInput(o,args,listView);
}
else
{
    listView.PreviewTextInput -= (o, args) => 
        listView_PreviewTextInput(o, args, listView);
}

Как я могу исправить или оптимизировать эту вещь

Ответы

Ответ 1

Вы можете извлечь lamdba для переменной:

EventHandler func = (sender, e) =>
    listView_PreviewTextInput(sender, e, listView);

if (((bool)e.NewValue))
{
    listView.PreviewTextInput += func;
}
else
{
    listView.PreviewTextInput -= func;
}

Ответ 2

Внимание! Принятый ответ от Steven неправильный, все, что он делает, просто маскирует проблему, о которой предупреждает resharper.

Выполняется каждый присваиваемый код

 EventHandler func = (sender, e) =>
     listView_PreviewTextInput(sender, e, listView);

вы получите новый (так как вы можете захватить другой listView) экземпляр анонимного делегата, сохраненный в func, экземпляр, который еще не подписан ни на какие события, поэтому, в свою очередь, этот код

listView.PreviewTextInput -= func;

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

На самом деле, Джон Скит говорит, что может работать в некоторых случаях:

В спецификации С# явно указано (IIRC), что если у вас есть два анонимные функции (анонимные методы или лямбда-выражения), это может или не может создавать равных делегатов из этого кода.

например. когда компилятор не генерирует новый экземпляр каждый раз, вы увидите приятное поведение.

Но это ненадежное и, конечно же, не будет работать в случае, описанном в стартовом вопросе с захваченной переменной listView.

Итак, мое предложение:

Использовать анонимные функции как обработчики событий ТОЛЬКО, если вам не придется отказаться от подписки.