When I was trying to learn events and delegates, I read a lot of articles to completely understand what they are and how to use them, and now I want to present them all here, everything I learned, most of the things you need to learn.

Delegate and Event concepts are completely tied together. Delegates are just function pointers, That is, they hold references to functions.

A Delegate is a class. When you create an instance of it, you pass in the function name (as a parameter for the delegate's constructor) to which this delegate will refer.

Every delegate has a signature. For example:

Delegate int SomeDelegate(string s, bool b);

is a delegate declaration. When I say this delegate has a signature, I mean that it returns an int type and takes two parameters of type string and bool.

I said, when you instantiate delegates, you pass in the function name to which this delegate will refer as its constructor parameter. The important thing to notice is that only functions that have the same signature as the delegate, can be passed as a parameter.

Consider the following function:

privateint SomeFunction(string str, bool bln){...}

You can pass this function to SomeDelegate's constructor, because of their similar signatures.

SomeDelegate sd = new SomeDelegate(SomeFunction);

Now, sd refers to SomeFunction, in other words, SomeFunction is registered to sd. If you call sd, SomeFunction will be invoked. Keep in mind what I mean by registered functions. Later, we will refer to registered functions.

This is the scenario: we have a class named Counter. This class has a method named CountTo(int countTo, int reachableNum) which starts counting from 0 to countTo, and raises an event named NumberReached whenever it reaches the reachableNum.

Our class has an event: NumberReached. Events are variables of type delegates. I mean, if you want to declare an event, you just declare a variable of type some delegate and put event keyword before your declaration, like this:

publicevent NumberReachedEventHandler NumberReached;

In the above declaration, NumberReachedEventHandler is just a delegate. Maybe it was better to say: NumberReachedDelegate, but notice that Microsoft doesn't say MouseDelegate or PaintDelegate, instead it offers: MouseEventHandler and PaintEventHandler. It's a convention to say NumberReachedEventHandler instead of NumberReachedDelegate. OK? Good!

You see, before we declare our event, we need to define our delegate (our event handler). It could be something like this:

As you see, our delegate's name is: NumberReachedEventHandler, and its signature contains a void return value and two parameters of type object and NumberReachedEventArgs. If you somewhere want to instantiate this delegate, the function passed in as constructor parameter should have the same signature as this delegate.

Have you ever used PaintEventArgs or MouseEventArgs in your code to determine the position of the mouse, where it was moving, or the Graphics property of the object which raised the Paint event? Actually, we provide our data for the user in a class which is derived from EventArgs class. For example, in our example, we want to provide the number which was reached. And here is the class definition:

Good question! If you want to know why we called indirectly, take another look at OnNumberReached's signature:

protectedvirtualvoid OnNumberReached(NumberReachedEventArgs e)

You see, this method is protected, it means it's available for classes which are derived from this class (inheriting classes).

This method is also virtual, this means that it could be overridden in a derived class.

And this is very useful. Suppose you are designing a class which inherits from Counter class. By overriding OnNumberReached method, you can do some additional work in your class before the event gets raised. An example:

Note that if you don't call base.OnNumberReached(e), the event will never be raised! This might be useful when you are inheriting from some class and want to eliminate some of its events! An interesting trick, huh?

As a real world example, you can just create a new ASP.NET Web Application and take a look inside the code behind generated. As you see, your page inherits from System.Web.UI.Page class. This class has a virtual and protected method name OnInit. You see that InitializeComponent() method is called inside the overridden method as an extra work, and then OnInit(e) is called in the base class:

#region Web Form Designer generated code
protectedoverridevoidOnInit(EventArgs e)
{
//CODEGEN: This call is required by the ASP.NET Web Form Designer.
InitializeComponent();
base.OnInit(e);
}
///<summary>/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///</summary>privatevoid InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion

Notice that NumberReachedEventHandler delegate is defined outside our class, inside the namespace, visible to all classes.

OK. Now, it's time to practically use our Counter class:

In our sample application, we have two textboxes named txtCountTo and txtReachable as follows:

Now, you understand what you are doing here! You are just instantiating an object of type NumberReachedEventHandler delegate (as you do for any other object). Care about the oCounter_NumberReached method signature similarity as I mentioned before.

And notice that we used += instead of simply =.

It's because delegates are special objects that can hold references to more than one object (here, reference to more than one function). For example, if you had another function named oCounter_NumberReached2 with the same signature as oCounter_NumberReached, both of the functions could be referenced this way:

A lot of folks keep asking this question: "what happens if we don't use event keyword?"

In essence, declaring the event keyword prevents any of the delegate’s users from setting it to null. Why is this important? Imagine that as a client I would add to the delegates invocation list a callback to one of my class’ functions. So would other clients. All is well and good. Now imagine that someone, instead of using the “+=”, is simply setting the delegate to a new callback by using “=”. This basically just throws the old delegate and its invocation list down the drain and creates a whole new delegate with a single item in its invocation list. All the other clients will not receive their callbacks when the time comes. It is this kind of situation that having the event keyword is aiming to solve. If I keep the event keyword in the Counter class and try to compile the following code in my application, it will cause a compilation error. By removing the event keyword, however, this error will not happen.

In conclusion: an event declaration adds a layer of protection on the delegate instance. This protection prevents clients of the delegate from resetting the delegate and its invocation list, and only allows adding or removing targets from the invocation list [reference].

Hey, the article is very informative. Indeed this expalined all from start till end.

I have a query with the page lifecycle events. When I set autoeventwireup = true, I can define the pageload without arguments and it works.
But when I set auto...=false and add the event manually in the class constructor..... Load += new eventHandler(Page_Load);

Hi
Whenever you set the AutoEventWireup to false, the event handler you provide (Page_Load in this case) should conform the signature of the corresponding delegate which in this case is 'System.EventHandler'.
That being said, the following code won't work because you haven't provided the event handler with the expected arguments:

Thanks again for great info. But I am having constant doubts with Page/Control lifecycle.

Here is what I am currently trying to do:
I want to create a custom control(a simple html 'select') by overriding render. How do I persist the selected option during postbacks?
More precisely, if I have an integer var _int, how can I set its value corresponding to selected option so that during render I can make that option selected? I am not able to find out the selected option in the 'select'.

I think you should be able to persist the current selected value by setting EnableViewState of your control (select control in this case) to 'true' which results in persisting the selected value in a ViewState object automatically. You can also do this manually by using ViewState object.

Hi,
I think multicast delegates should be included. Multcast delegates are those delegates which are subscribed ore registered by more than one functions. The primary condition is delegates should be void. Then only we can multicast it. Simple example like this will explain the concept.

Exceptions in multicast delegates:
Suppose you have added multiple delegates to a single multicast delegate. Each of these individual delegates must be invoked, regardless of whether an unhandled exception is thrown within one of the delegates. But once a delegate in a multicast delegate throws an unhandled exception, no more delegates are fired. You need a way to trap unhandled exceptions within each individual delegate while still allowing the rest of the delegates to fire.

To avoid the breaking of the chain you have to gracefully handle exception in all functions. Use the GetInvocationList method. This method returns each individual delegate from a multicast delegate and, by doing so, allows you to invoke each delegate within the try block of an exception handler.

like everyone else, thanks for the article, its a lot better than most. I just have a couple of issues with it really. Delegates seem to be something that a lot of people new to C# encounter and have problems with. I think in many cases they have problems with OOP which really doent help when you are trying to learn C#.

I think it sould be pointed out that the following code is bad from a OO perspective. Client code should never be given access to what should be a private member; this is just plain wrong.

public class Counter
{
public event NumberReachedEventHandler NumberReached; //WRONG - should be private

public Counter()
{

This forces to much work on the client code.

Please dont get me wrong, I love your article, it is what has helped me understand delegates, but I come from the world of Java, and from what I can see, the Java event model is far cleaner and does a better job of things; if only on a superfical, user friendly level.

All a client class should have to do is register an interest in receiving a particular event, subscribe to that event and that is it.

You know what, Im not making mych sence here, I am going to go and write an article instead.......

public event NumberReachedEventHandler NumberReached; //WRONG - should be private

The NumberReached event must be public for other classes to subscribe (i.e. +=) and unsubscribe (i.e. -=) to the event. When you put an access specifier (such as public or private) on an event, it controls who can register or listen to that event. Invoking an event can only be done from within the class that declared the event, even if the event is public!

From the IDE, the user can define an event for the control - in this case It's the Validated one.

In runtime, when you Tab to another control the validation works fine. The problem here is how can I link the internal TextBox´s Validated event to raise the parent´s one, considering there are a couple of sibling controls inside the same parent?

MyControl.TextBox
MyControl.Button
MyControl.Label

I´d hear about delegates but they work only on predefined methods in the parent which is not the case, 'cause the definition of the event can or cannot exist, it´s a dynamic setup.

The "Bad code" comment refers to the method used to check whether someEvent is null. It does not mean that the protected virtual OnSomeEvent() pattern is bad.

The example code has a thread race condition. When someEvent is checked for null, it may be non-null. BUT! In the brief instant after the if and before the someEvent function call, another thread might unsubscribe the last event listener. This would make someEvent null and cause the function call to throw a NullReferenceException!

Hi Man this is very nice and good article, I was having same problem as other had to understand this event and delegates. But it’s much clear to me.  But I have one question. You said we can use event to inform the users about weather change, don’t you think we need some sort or remote programming because I think this is not so easy to just use event and make a complete application which show weather change to registered users. Sorry to my English I am not good in English. Actually I am trying to make some application based on event, what I want is I just type a message and my all users can see this msg. any help or any link if you got pls reply me

This is a great article, but I'm confused how events and delegates relates to threading.

My understanding is that event handlers are required for UI code so because the forms classes are not threadsafe. So if for example a worker thread needs to modify the GUI, then it needs to use an event to signal the main thread to actually do the work.

1. But if a delegate is simply a function pointer to a function in another class, then won't the event method be called by the worker thread anyway?

2. Or when you use an event does the run-time interrupt the main thread so that it actually calls the event code?

3. If (2) is true, then in general how do you control which thread executes which code?

Thanks in advance for any responses to clarify this (or links to other articles).