Событие Unsubscription через анонимный делегат [Duplicate

StackOverflow https://stackoverflow.com/questions/8803064

  •  26-10-2019
  •  | 
  •  

Вопрос

Этот вопрос уже имеет ответ здесь:

Я использую анализ кода 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);
}

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

Это было полезно?

Решение

Вы можете извлечь ламдбу в переменную:

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

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

Другие советы

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

Каждый раз, когда данный код выполняется

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

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

listView.PreviewTextInput -= func;

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top