views:

368

answers:

2

Been doing this for a while but haven't noticed I have been using a "new" each time I remove an event handler. Am I supposed to be creating a new object?

Basically is there a difference between 1 and 2?

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

(2)ethernetdevice.PcapOnPacketArrival -= ArrivalResponseHandler;

EDIT: Okay this is a repeat. Sorry about that. Answer posted here: http://stackoverflow.com/questions/1307607/removing-event-handlers

Two delegates of the same type with the same targets, methods, and invocation lists are considered equal.

+7  A: 

The second version is equivalent to the first; it just uses a shorter syntax. This was implemented in C# 2.0

Adam Maras
+3  A: 

There is no difference between 1 and 2, because 2 is syntactic sugar for 1. Only if 2 referred to a class-level delegate instance field rather than the actual method name would there be a difference in the compiled IL.

In terms of what happens at runtime, the event Remove method does not seem to care whether or not the delegate instance passed to it is the same one as the one passed to the Add method. I can't remember off-hand why this is, but I would guess that delegate instances are always interned.

EDIT: Jon Skeet says that the event Remove method uses value equality (Delegate.Equals) to determine which delegate to remove from the list, rather than interning + reference equality. Same end result, different method. :-)

Christian Hayter
Since a delegate is just a reference to a method and an (optional) instance, comparing those two should be enough for determining equality.
Botz3000
Yes, but generally speaking, if you call `new T()` twice on an arbitrary reference type you would get two different instances. Since this seems not to be the case for delegates, I deduce that the delegate constructor is automatically interning the instances just like the `Type` class does.
Christian Hayter
interned - what does that mean? Thanks for the answer. This kind of addresses the doubt I had. I was wondering about that new as I am creating a new instance when I add a handler and creating a new one when I remove it. Very weird.
Klerk
@Christian: No, it's not interning anything - it's just using Delegate.Equals, which compares the method and the target.
Jon Skeet
Interning is when you check whether an existing instance with the same value already exists before creating a new one. If such an instance exists, you return that instance instead. This guarantees that only unique instances of the type exist in memory. For example, strings are always interned at compile time, but not at run time unless you call `String.Intern` manually.
Christian Hayter
@Jon: ...and that's the other explanation that didn't occur to me. :-) Thanks for the info.
Christian Hayter
Learnt something new today. Thanks Christian!
Klerk