2009-09-28 6 views
26

Я делал это некоторое время, но я не заметил, что каждый раз, когда я удаляю обработчик событий, я использую new. Должен ли я создавать новый объект?C# удаление обработчика событий

В принципе есть разница между 1 и 2?

  1. ethernetdevice.PcapOnPacketArrival -= new SharpPcap.PacketArrivalEvent(ArrivalResponseHandler);

  2. ethernetdevice.PcapOnPacketArrival -= ArrivalResponseHandler;

EDIT: Хорошо это дубликат. Извини за это. Ответ отправлен here.

Два делегата одного типа с одинаковыми целями, методами и списками вызовов считаются равными.

ответ

29

Нет никакой разницы между 1 и 2, потому что 2 является синтаксическим сахаром для 1. Только если 2, упомянутый в поле экземпляра делегата класса класса, а не в имени фактического метода, будет разница в скомпилированном ИЛ.

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

EDIT: Джон Скит говорит, что метод события Remove использует значение равенства (Delegate.Equals), чтобы определить, какой делегат удалить из списка, а не интернирование + равенства ссылок. Тот же конечный результат, другой метод. :-)

+0

Поскольку делегат - это просто ссылка на метод и (необязательный) экземпляр, сравнение этих двух должно быть достаточным для определения равенства. – Botz3000

+0

Да, но, вообще говоря, если вы вызываете 'new T()' дважды на произвольный тип ссылки, вы получите два разных экземпляра. Поскольку это не соответствует делегатам, я выводю, что конструктор делегата автоматически выполняет экземпляры, как это делает класс 'Type'. –

+0

интернированный - что это значит? Спасибо за ответ. В этом вопросе я сомневаюсь. Мне было интересно об этом новом, поскольку я создаю новый экземпляр, когда добавляю обработчик и создаю новый, когда я его удаляю. Очень странно. – Sharun

13

Вторая версия эквивалентна первой; он просто использует более короткий синтаксис. Это было реализовано в C# 2.0.

Смежные вопросы