28

I've been doing this for a while, but I haven't noticed that I've 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 duplicate. Sorry about that. Answer posted here.

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

Community
  • 1
  • 1
Sharun
  • 2,030
  • 4
  • 22
  • 36

2 Answers2

32

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
  • 30,581
  • 6
  • 72
  • 99
  • Since a delegate is just a reference to a method and an (optional) instance, comparing those two should be enough for determining equality. – Botz3000 Sep 28 '09 at 09:55
  • 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 Sep 28 '09 at 10:00
  • 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. – Sharun Sep 28 '09 at 10:10
  • 3
    @Christian: No, it's not interning anything - it's just using Delegate.Equals, which compares the method and the target. – Jon Skeet Sep 28 '09 at 10:17
  • 2
    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 Sep 28 '09 at 10:21
  • @Jon: ...and that's the other explanation that didn't occur to me. :-) Thanks for the info. – Christian Hayter Sep 28 '09 at 10:23
  • Learnt something new today. Thanks Christian! – Sharun Sep 28 '09 at 10:26
13

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

Adam Maras
  • 26,269
  • 6
  • 65
  • 91