views:

607

answers:

6

I'm little confused, I know that delegates are like function pointers, and they are used to pass a function as a parameter into a method.

How does that fit into the event model?

Calling:

myButton.OnClick += new .....();

Is that internally just passing the method/function as a parameter when the event occurs and all the subscribers are notified about the event?

+7  A: 

Have a look at this

Curiosity is bliss

astander
+1 -- Good link.
Frank V
Good blog. I really like Julien Couvreur.
Lucas McCoy
+1  A: 

The event, which in the case of a button Click is the "Click" event, is acting as the "function pointer" here. Meaning, when you add your method to it using the += syntax, you're essentially making the Click Function Pointer POINT to your function. Therefore, when the button is clicked, the Click Function Pointer calls all of the functions its pointing to. Makes sense?

BFree
+2  A: 

The event has two operators; add and remove. When you add an event handler (as in your example), the event will get a reference to the method, and add it to its list of subscribed event handlers. When the event is raised, it will go through the list and invoke the methods in it.

Fredrik Mörk
+2  A: 

When you do:

myButton.OnClick += new ...();

You're adding your delegate as a subscriber to that event. When the event is raised later on, all subscribers will be called (with no guarantees about order). This is called a multicast delegate. It is kinda like a function pointer with the added bonus of allowing it to "point" to more than one function.

Note that now you don't need to explicitly create the delegate, you can just use the method name:

myButton.OnClick += MethodName;

And don't forget that you can (and should, see why) unsubscribe from events you subscribed to prevent leakage:

myButton.OnClick -= MethodName;
Martinho Fernandes
A: 

The Button has a private "multicast delegate" field and the public property-like "Click" that you use the += and -= operators with is an automatically generated way to manage the state of that private field.

When the button raises the click event internally, it is invoking that private multicast delegate, which will invoke all the delegates that it currently knows about.


This system can be confusing when first implementing your own events, because the same identifier, "EventName", refers to one thing inside your class (the private multicast delegate field) and another thing outside of your class (the public management mechanism for that field).

frou
For events, the accessors are not `get` and `set` though. They are `add` and `remove`.
Mehrdad Afshari
A: 

Indeed, a delegate is much like a function pointer. The first difference is that a delegate is composed by 2 "pointers": a function pointer and an instance pointer. Not surprisingly, the Delegate class has these two properties:

// Gets the method represented by the delegate.
public MethodInfo Method { get; }

// Gets the class instance on which the current delegate
// invokes the instance method.
public object Target { get; }

The second difference is that .NET delegates can be multicast. It's possible to add two delegates in a single MulticastDelegate. It's also possible to remove a delegate from a multicast delegate. When invoked, a multicast delegate will invoke all its child delegates. This may drive other questions, but I would be deviating from the original question.


An event, on the other hand, is a completely different stuff. In fact, an event is a property with special accessors. Regular properties have these two accessors: get and set. Events have these two instead: add and remove.

The add accessor will combine the current delegate that is in the event with the new delegate into a multicast delegate. The remove accessor will do the opposite.

Having that in mind, it's easy to understand why C# designers picked out the += and -= operators. What I mean is that the following two lines are somewhat equivalent (if you ignore that fact that the second).

myButton.OnClick += newEventHandler;
myButton.OnClick = myButton.OnClick + newEventHandler;
jpbochi