Home > .Net / C# > Delegates and Events in C#

Delegates and Events in C#

Article overview

In this article series, I’m going to review the basic features and techniques used behind the Language Integrated Query (LINQ), including :

  • Delegates
  • Events (which are not directly related to LINQ, but are very closely related to delegates)
  • Lambda expressions (Anonymous functions)
  • Extension methods

At the end, I’ll summarize them and, hopefully, you will possess a better understanding of how LINQ works. ;)

Related articles:

 


What is a delegate in C# ?

A delegate in C# is a class that holds pointers to one or more methods for later execution. It’s a wrapper that provides dynamic invocation on the stored method references, both synchronious and asynchronious, along with some related meta-information. In its simplest form, a delegate is just a pointer to a function.


Why were the delegates  introduced ?

The delegates in C# were introduced in order to allow the developers to use techniques from the functional programming world in the procedural environment of the .Net platform.

For example, the delegates can be assigned to a variable and passed as function parameters, effectively making them “first class citizens”. That way, the inner workings of the methods can be replaced “dynamically” in a very elegant and effective way like, for instance, in LINQ, which is based on anonymous functions, extension methods and delegates.

 

Delegate basics

The delegate in its simplest form

As I mentioned, the delegate is just a class like the one below :

This forms the very basic implementation of a delegate that derives from System.MulticastDelegate and System.Delegate, respectively. The method Invoke() calls the actual stored method, which in this case should be declared with two parameters of type integer. The other two methods – BeginInvoke() and EndInvoke() – are used in an asynchronous scenarios, when you need to execute the stored function in a different thread than the calling one.


The delegate shortcut

Luckily, we are not required to manually write the declaration and definition of the class shown above. The following declaration will automatically generate the code for us behind the scenes :

For example :

If you explore the intellisense output on  the delegate, you’ll notice that it contains a number of additional methods.

delegates-intellisense

 

Using the method group conversion feature

Take a look on the following line :

Instead of instantiating the delegate class using the new keyword, we can use a feature called Method Group Conversion to directly assign the method to the delegate pointer. For instance :

 

Using the multicast feature

Remember when I said that delegates store pointers to one or more methods ? Storing and calling multiple methods is called multicasting and can be achieved the following way :

When you invoke the delegate implicitly or explicitly, all the stored methods will get invoked. The snippet above uses operator overloading, which is a really cool feature that originates from C++.

 

Using the predefined delegates

The truth is that you rarely want or need to define any delegates yourself. There is a group of predefined generic delegates which you can use when you need a rather standard implementation :

Some of them have similar declarations, but they are semantically different. Namely, if you want to point to a predicate, you’ll use the Predicate<T> class, even if there is a Func<T1, Result>  that takes practically the same arguments.

 

Events basics

What are the events in C Sharp ?

The events in C# are in fact simple wrappers around the delegates, which provide few convenient features that are really just a syntactic sugar. Consider the following example :

We have the Operations class that performs some business logic and that we want to observe (which is basically an implementation of the Observer pattern using the latest .Net features). We see the delegate member, which is declared as private and, we see a pair of accessors – a getter and a setter.

The whole idea is, of course, to provide an appropriate encapsulation. We don’t want to give exclusive access to our delegate, we don’t want anyone to be able to override the delegate’s already established list of methods. That’s why we declare it as private, and that’s why we provide accessor methods


So, what are the events after all ?

The events in C Sharp generate some of the code for you and provide few more minor conveniences. The following declaration

will actually generate

  • A private declaration of a delegate of the specified class
  • Accessors (a getter and a settor), which prohibits the user from directly accessing the delegate and it’s methods


In addition to that, the events provide the following conveniences :

  • An event can be used in an interface declaration, while a delegate can not
  • An event can only be invoked from the class in which it is declared
  • The event has to be declared in a specific way


Using events, our example becomes the following :

Notice that if we attempt to assign a new value to the callback

a compile-time error will be thrown. In fact, the IDE itself will warn us before that.


Using the proper convention for declaring events

As I said in the previous section, the event has to be declared in a specific way. Or at least it’s a good practice to define in that way, using the following pattern :

You see the first parameter which is of type System.Object, and the second parameter, which is in fact a custom type that derives from System.EventArgs

If you take a look on all the standard Microsoft event implementations, you’ll notice exactly this pattern. It decouples the event declaration from the actual parameters passed, making them more orthogonal.


Conclusion

Pointing to methods, using them as variables and passing them through functions is in fact a very powerful technique. Although I would not use a pure functional programming language for everyday use, I do admire the benefits that come from this hybrid approach.

In this article, I’ve made a brief overview of the delegates in C#, which are critical for understanding the inner workings of LINQ. In my next articles on the topic, I’ll talk about Anonymous functions and Extension methods.

LINQ internals (Part 2): Lambda expressions


About the author:
Kosta Hristov (34 Posts)

Hi there ! My name is Kosta Hristov and I currently live in London, England. I've been working as a software engineer for the past 6 years on different mobile, desktop and web IT projects. I started this blog almost one year ago with the idea of helping developers from all around the world in their day to day programming tasks, sharing knowledge on various topics. If you find my articles interesting and you want to know more about me, feel free to contact me via the social links below. ;)




Like the article ? Share it ! ;)


  1. No comments yet.
  1. No trackbacks yet.

Current month ye@r day *


Copyright © Developing the future 2013. Licensed under the CC BY-NC-ND 3.0 Creative Commons license.