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.

1

2

3

4

5

6

7

template<classT>TAddition(Toperand1,Toperand2){

Tresult;

result=operand1+operand2;

returnresult;

}

Delegate basics

The delegate in its simplest form

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

1

2

3

4

5

6

sealedclassOperation:System.MulticastDelegate

{

publicintInvoke(intx,inty);

publicIAsyncResultBeginInvoke(intx,inty,AsyncCallbackcb,objectstate);

publicintEndInvoke(IAsyncResultresult);

}

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 :

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 :

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

namespaceTest_ConsoleApp

{

publicdelegatevoidOperationInvoked(stringmessage);

publicclassOperations

{

privateOperationInvokedcallback=null;

publicvoidRegisterEvent(OperationInvokedfunction)

{

this.callback+=function;

}

publicvoidUnRegisterEvent(OperationInvokedfunction)

{

this.callback+=function;

}

publicintAddition(intop1,intop2)

{

this.callback("Addition performed.");

returnop1+op2;

}

publicintSubsctraction(intop1,intop2)

{

this.callback("Substraction performed.");

returnop1-op2;

}

}

publicclassProgram

{

publicstaticvoidMain(string[]args)

{

OperationsoperationsInstance=newOperations();

operationsInstance.RegisterEvent(Program.PrintMessage);

operationsInstance.Addition(1,2);

operationsInstance.Subsctraction(1,2);

Console.ReadLine();

}

publicstaticvoidPrintMessage(stringmessage)

{

Console.WriteLine(message);

}

}

}

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

1

publiceventOperationInvokedoperationPerformedEvent;

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 :

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

namespaceTest_ConsoleApp

{

publicdelegatevoidOperationInvoked(stringmessage);

publicclassOperations

{

publiceventOperationInvokedcallback;

publicintAddition(intop1,intop2)

{

this.callback("Addition performed.");

returnop1+op2;

}

publicintSubsctraction(intop1,intop2)

{

this.callback("Substraction performed.");

returnop1-op2;

}

}

publicclassProgram

{

publicstaticvoidMain(string[]args)

{

OperationsoperationsInstance=newOperations();

operationsInstance.callback+=Program.PrintMessage;

operationsInstance.Addition(1,2);

operationsInstance.Subsctraction(1,2);

Console.ReadLine();

}

publicstaticvoidPrintMessage(stringmessage)

{

Console.WriteLine(message);

}

}

}

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

1

operationsInstance.callback=Program.PrintMessage;

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 :

1

publicdelegatevoidOperationInvoked(objectsender,OperationArgse);

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

1

2

3

4

5

6

7

8

publicclassOperationEventArgs:EventArgs

{

publicreadonlystring_message;

publicOperationEventArgs(stringmessage)

{

_message=message;

}

}

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.

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. ;)