This the following is really a great masterpiece of explanation and grasp of language
<>
For Source ClickMe
To understand event handlers, you need to understand delegates. In C#, you can think of a delegate as a pointer (or a reference) to a method. This is useful because the pointer can be passed around as a value.
The central concept of a delegate is its signature, or shape. That is (1) the return type and (2) the input arguments. For example, if we create a delegate
void MyDelegate(object sender, EventArgs e) , it can only point to methods which return void , and take an object and EventArgs . Kind of like a square hole and a square peg. So we say these methods have the same signature, or shape, as the delegate.
So knowing how to create a reference to a method, let's think about the purpose of events: we want to cause some code to be executed when something happens elsewhere in the system - or "handle the event". To do this, we create specific methods for the code we want to be executed. The glue between the event and the methods to be executed are the delegates. The event must internally store a "list" of pointers to the methods to call when the event is raised.* Of course, to be able to call a method, we need to know what arguments to pass to it! We use the delegate as the "contract" between the event and all the specific methods that will be called.
So the default
EventHandler (and many like it) represents a specific shape of method (again, void/object-EventArgs). When you declare an event, you are saying which shape of method(EventHandler) that event will invoke, by specifying a delegate:
(*This is the key to events in .NET and peels away the "magic" - an event is really, under the covers, just a list of methods of the same "shape". The list is stored where the event lives. When the event is "raised", it's really just "go through this list of methods and call each one, using these values as the parameters". Assigning an event handler is just a prettier, easier way of adding your method to this list of methods to be called).
| |||
|
And now can anyone explain why the event is called EventHandler?? Of all the confusing naming conventions, this is the worst... – Joel in Gö Jun 11 '09 at 11:12
| ||
|
@Joel in Go the event is not called EventHandler - EventHandler is the contract the event must have with anyone who communicates with it. It's like "string MyString" - the string is declaring the type. event MyEventHandler TheEvent is declaring that anyone who interacts with this event must conform to the MyEventHandler contract. The Handler convention is because the contract primarily describes how to handle the event. – Rex M Jun 11 '09 at 13:26
| ||
|
How is the event fired? – alchemical Mar 22 '10 at 18:02
| ||
|
@LuftMensch from inside the class which owns the event, the syntax
EventName(delegateArg1, delegateArg2); is valid. That invokes the event like a method, which kind of kicks off a chain, calling each handler assigned to that event with those arguments. – Rex M Mar 22 '10 at 19:00 | ||
|
@Rex M : thank you for the first coherent explanation for "MyEventHandler" that I have ever seen :) – Joel in Gö Apr 21 '10 at 12:01
| ||
@Rex M - What if you wanted to handle an event from a class that does not own the (static)object that owns the event? Like here: stackoverflow.com/questions/4816892/… – wulfgarpro Jan 29 '11 at 3:00
| |||
Great answer. I just read it and it brought me up to speed in no time. I would only add that the thing that should fire/raise/call the event is a listener. The listener is probably polling something like keyboard input / mouse input constantly, so it should launch a separate thread when it listens for a thing (otherwise it would hang). Then when that thing happens, it can call SomethingHappened(TheTriggeringString). – user420667Feb 12 '12 at 4:18
| |||
@user420667 thanks for the kind word. Something to keep in mind - eventing isn't only for external triggers. Sometimes it is useful for inverting normal program flow as well, which means there is not necessarily a poller on a separate thread. So the thing that initiates the event is separate from the concept of eventing itself. – Rex M Feb 13 '12 at 22:22
| |||
|
@Joel in Go: I felt the same way, until I started reading it as: public event<MyEventHandler> eventName :)– Michael Parker Mar 7 '13 at 14:49
| ||
|
Thank you for the phase: "The glue between the event and the methods to be executed are the delegates. ",this is really awesome. – zionpi May 10 '13 at 8:05
| ||
|
Just want to mention: "HandleSomethingHappened" is often called "OnSomethingHappened" – HoKy22 Dec 4 '13 at 20:42
| ||
|
important to note WHY the
event keyword is required. It restricts access to types that do not own the event to += and -= only – Gusdor Jan 6 '14 at 13:34 | ||
do you have to use += new MyEventHandler(...)? can i write +=MyEventHandler(sting foo)? MyEventHandler is a delegate – user2975699 Apr 12 '14 at 21:54
| |||
|
@user2975699 a delegate is an object, so you have to create a new instance of it. c# also allows a shorthand, Event += TheMethod. Here if it detects the method is compatible with the delegate type of the event, it'll implicitly create the delegate instance for you. – Rex M Apr 13 '14 at 14:13
| ||
|
@user2975699 you can also create an anonymous method in-line that will implicitly get a delegate: Event += (args) => //do something – Rex M Apr 13 '14 at 14:19
| ||
Thanks for your well thought out post. It's worth mentioning the standard format: public delegate void MyEventHandler(object Sender, MyEventArgs e) where MyEventArgs derives from EventArgs. Seemsdn.microsoft.com/en-us/library/aa645739%28v=vs.71%29.aspx. This offers the benefit of following the generic system.eventhandler that's been built in since .Net 2.0 which allows you to use public event MyGenericEventHandler<MyPublisher, MyEventArgs> MyEvent. See codeproject.com/Articles/20550/…. – VoteCoffee Aug 11 '14 at 22:10
| |||
See msdn.microsoft.com/en-US/library/ms182178%28v=vs.80%29.aspx. It allows you to skip some of the extra work in declaring delegates, etc. – VoteCoffee Aug 11 '14 at 22:14
| |||
The most wonderful explanation of anything i have seen in stackoverflow. – Rama Krshna Ila Jan 19 at 23:43
| |||
@RexM thanks for your answer Rex. I have one question. What do you mean by "raising an event"? How would 'raising an event' look like in c# code? – BKSpurgeon Mar 6 at 1:03
| |||
|
@BKSpurgeon from anywhere inside the class that declares the event, you would call it like a method:
this.SomethingHappened(args); . If there are no subscribers though, SomethingHappened will be null, so make sure you check for null before trying to call it. – Rex M Mar 6 at 13:47 |