Friday, July 29, 2011

Delegates and Events

Delegates

Tutorial

A delegate in C# is similar to a function pointer in C or C++. Using a delegate allows the programmer to encapsulate a reference to a method inside a delegate object. The delegate object can then be passed to code which can call the referenced method, without having to know at compile time which method will be invoked. Unlike function pointers in C or C++, delegates are object-oriented, type-safe, and secure.

Encapsulation of Methods in Delegate

A delegate declaration defines a type that encapsulates a method with a particular set of arguments and return type. For static methods, a delegate object encapsulates the method to be called. For instance methods, a delegate object encapsulates both an instance and a method on the instance. If you have a delegate object and an appropriate set of arguments, you can invoke the delegate with the arguments.

Anonymous invocation

An interesting and useful property of a delegate is that it does not know or care about the class of the object that it references. Any object will do; all that matters is that the method's argument types and return type match the delegate's. This makes delegates perfectly suited for "anonymous" invocation.

Security

Delegates run under the caller's security permissions, not the declarer's permissions.

Properties of delegate

Delegates are similar to object references, but are used to reference methods instead of objects. The type of delegate is the type or signature of the method rather than the class. Hence a delegate has three properties:-
1.       The type or signature of the method that a delegate can point to.
2.       The delegate reference, which can be used to reference a method.
3.       The actual method referenced by a method.
The concept of the delegate is similar to the function pointer in C++.
We are going to describe each and every property of delegate.

The type or signature of the method that a delegate can point to

Before using delegate, we need to specify the type or signature of the method the delegate can references. The signature of the method includes its return type and the type of parameters which it requires to be passed.




For example:
Please have a look into “Add()” method given below :
int Add(int num1, int num2)

The signature for above method could be like:
int aMethod(int num1, int num2)

This could be also a signature of “Subtract” method:
int Subtract(int num1, int num2)

It should be noticed from above example that the name of the method is not a part of signature. The signature only involves its return type and parameters.

Declaration: Signature of Delegates


We define the type of delegate using the delegate keyword.

delegate int MyDelegate(int num1, int num2);

Here we have defined a delegate type with name “MyDelegate”. The reference of this delegate type can be used to point any method which takes two integers as parameters and returns an integer value.

Registration: The delegate reference that can be used to reference a method


Once we have declared the delegate type, we can set it to reference actual methods with matching signatures. A delegate reference can be declared just like an object reference. For example, a reference of type MyDelegate (defined above) can be declared as:
MyDelegate arithMethod;

The delegate reference “arithMethod” can  now reference any method whose signature is identical to the signature of “MyDelegate”.

The actual method referenced by the delegate.

The delegate reference can be made to reference any method with a matching signature by passing its name as the parameter of delegate:
//Object of a class.
DelegateExamples delegateExmple = new DelegateExamples();

//initialization of delegate: making a delegate reference and assigning a method to it.
MyDelegate arithMethod = new MyDelegate(delegateExmple.Add);

Here, the “arithMethod” delegate reference is made to point to the “Add()” method of class “DelegateExamples” by passing its name as a parameter to delegate type “MyDelegate”.

Initialization: Calling actual method through its delegate

Once the delegate reference has been made to point to the “Add()” method of class “DelegateExamples”, it can be used to call the actual method. For example:
//Calling the actual method through delegate.
int result = arithMethod(4, 5);

Confusion in terminology

Unfortunately, the same term “Delegate” is used for both “delegate type” and “delegate reference”, which sometimes creates confusion in the reader’s mind.

Passing a delegate to a Method

Just like a reference to an object can be passed to other objects, the delegate reference of one method can be passed to another method. For example,
void PerformArithmeticOperations(int num1, int num2, MyDelegate arithMethod)

Multicast Delegate

A single delegate that encapsulates more than one method called Multicast Delegate. Internally, multicast delegates are sub-types of the “System.MulticastDelegate”, which itself it sub class of “System.Delegate”.

Point to be remember for Multicast Delegate

The return type of multicast delegate must be VOID.
The reason for this limitation is that a multicast delegate might have multiple methods in its invocation list. Since a delegate (or method) invocation can return only a single value, a multicast delegate type must have the void return type.

Implementing a Multicast Delegate

The multicast delegate is defined in exactly the same way as a simple delegate, with the exception that the return type of a multicast delegate is strictly a VOID.
//declaration of a Multicast Delegate TYPE
delegate void MyMulticastDelegate(int num1, int num2);

//initialization of multicast delegate REFERENCE: making an
 //delegate reference and assigning a method to it.
MyMulticastDelegate arithMethod = new MyMulticastDelegate(muslticastDelegateExmple.Add);
arithMethod += new MyMulticastDelegate(muslticastDelegateExmple.Subtract);
arithMethod += new MyMulticastDelegate(muslticastDelegateExmple.Multiply);
arithMethod += new MyMulticastDelegate(muslticastDelegateExmple.Divide);

The invocation of a multicast delegate calls all encapsulated method.
//Calling Multicast Delegate
arithMethod(5, 7);

NOTE: A single delegate invocation invokes all of the encapsulated methods.

Removing a method from the multicast delegate’s invocation list

We can remove a method from the multicast delegate’s invocation list by using “-=”. For example:
//initialization of multicast delegate REFERENCE: making an
 //delegate reference and assigning a method to it.
MyMulticastDelegate arithMethod = new MyMulticastDelegate(muslticastDelegateExmple.Add);
arithMethod += new MyMulticastDelegate(muslticastDelegateExmple.Subtract);

//Removing method from Multicast Delegate invocation list.
arithMethod -= new MyMulticastDelegate(muslticastDelegateExmple.Add);

Events and Event Handling

Events are certain actions that happen during the execution of a program that the application wishes to be notified about, so it can respond.
An event is basically a message which is said to be fired or triggered when the respective action occurs.
A CLASS that raises an event is called an “Event Sender”.
A CLASS that receives an event is called an “Event Consumer”.
A METHOD which is used to handle a particular event is called an “Event Handler”.
NOTE: Event handling in .Net follows the Publisher-Subscriber and Observer Design Patterns.
In .Net events are implemented as Multicast Delegates. In C# events are a fist class (basic) language construct, and defined using the event keyword.

No comments:

Post a Comment