A delegate is a type that safely wraps/encapsulates a method. It is similar to 'function pointers' in C/C++, but it's type safe.
When to Use a Delegate
Use a delegate when:
- An eventing design pattern is used.
- It is desirable to encapsulate a
static
method. - The caller has no need to access other properties, methods, or interfaces on the object implementing the method.
- Easy composition is desired.
- A class may need more than one implementation of the method.
There was a good example given in a book that I recently referenced.
'Consider your will—your last will and testament. It’s a set of instructions—“pay the bills, make a donation to charity, leave the rest of my estate to the cat,” for instance. You write it before your death, and leave it in an appropriately safe place. After your death, your attorney will (you hope!) act on those instructions.'
In order for a delegate to proceed, the following four things need to happen:
- The delegate type needs to be declared.
- There must be a method containing the code to execute.
- A delegate instance must be created.
- The delegate instance must be invoked.
Declaring Delegate Type
Declaration of a delegate type specifies what kind of action can be represented by instances of the type.
For example:
delegate void MySampleDelegate(string zParameter)
If we are creating an instance of the above delegate, we should have a method with one string
parameter and void
return type.
Method Containing the Code to Execute
There should be a method which matches the signature of the delegate. Method can be either static
or non static
. I will take two examples to illustrate a static
method and a non static
method. I will use the following two methods in the 'DelegateClass
' class.
For example:
public class DelegateClass {
public static void MySampleDelegateMethodStatic(string zParameter) {
Console.WriteLine("From static method. Parameter : {0}", zParameter);
}
void MySampleDelegateMethodNonStatic(string zParameter) {
Console.WriteLine("From non static method. Parameter : {0}", zParameter);
}
}
Creating a Delegate Instance
When creating delegate instances, static
methods can be passed directly. But for non static
methods, an instance should be created and passed to the delegate.
For example: [Static Method]
MySampleDelegate delMethodA = new MySampleDelegate(
DelegateClass.MySampleDelegateMethodStatic);
For example: [Non Static Method]
DelegateClass deligateClass = new DelegateClass();
MySampleDelegate delMethodB = new MySampleDelegate(
deligateClass.MySampleDelegateMethodNonStatic);
Or:
MySampleDelegate delMethodB = new MySampleDelegate(
new DelegateClass().MySampleDelegateMethodNonStatic);
Invoking Delegate Method
It's a matter of calling the Invoke
method on the delegate instance.
For example:
delMethodA.Invoke("Parameter A");
delMethodB.Invoke("Parameter B");
Here is the complete source code for the above example. I have used a console application to illustrate this:
using System;
using System.Text;
namespace SampleConsoleApplicationA {
delegate void MySampleDelegate(string zParameter);
class Program {
static void Main(string[] args) {
MySampleDelegate delMethodA =
new MySampleDelegate(DelegateClass.MySampleDelegateMethodStatic);
MySampleDelegate delMethodB = new MySampleDelegate(
new DelegateClass().MySampleDelegateMethodNonStatic);
delMethodA.Invoke("Parameter A");
delMethodB.Invoke("Parameter B");
Console.ReadLine();
}
}
public class DelegateClass {
public static void MySampleDelegateMethodStatic(string zParameter) {
Console.WriteLine("From static method. Parameter : {0}", zParameter);
}
public void MySampleDelegateMethodNonStatic(string zParameter) {
Console.WriteLine("From non static method. Parameter : {0}", zParameter);
}
}
}
And when you run your application, you will get the following output:
Instead of using separate delegate instances, you can combine and execute delegates. We have to use the 'Combine
' method in Delegate
class. To illustrate this, I will alter my 'DelegateClass
' as shown below:
public class DelegateClass {
public void MySampleMethodA(string zParameter) {
Console.WriteLine("MySampleMethodA. Parameter : {0}", zParameter);
}
public void MySampleMethodB(string zParameter) {
Console.WriteLine("MySampleMethodB. Parameter : {0}", zParameter);
}
public void MySampleMethodC(string zParameter) {
Console.WriteLine("MySampleMethodC. Parameter : {0}", zParameter);
}
}
To create instances and invoke:
MySampleDelegate[] mySampleDelegates = new MySampleDelegate[]{
new MySampleDelegate(new DelegateClass().MySampleMethodA),
new MySampleDelegate(new DelegateClass().MySampleMethodB),
new MySampleDelegate(new DelegateClass().MySampleMethodC)
};
MySampleDelegate sample = (MySampleDelegate)Delegate.Combine(
mySampleDelegates);
sample.Invoke("Parameter X");
Or:
MySampleDelegate D, deligateA, deligateB, deligateC;
deligateA = new DelegateClass().MySampleMethodA;
deligateB = new DelegateClass().MySampleMethodB;
deligateC = new DelegateClass().MySampleMethodC;
D = deligateA + deligateB + deligateC;
D("Parameter X");
The complete source code is as follows:
using System;
using System.Text;
namespace SampleConsoleApplicationA {
delegate void MySampleDelegate(string zParameter);
class Program {
static void Main(string[] args) {
MySampleDelegate[] mySampleDelegates = new MySampleDelegate[]{
new MySampleDelegate(new DelegateClass().MySampleMethodA),
new MySampleDelegate(new DelegateClass().MySampleMethodB),
new MySampleDelegate(new DelegateClass().MySampleMethodC)
};
MySampleDelegate sample = (MySampleDelegate)Delegate.Combine(
mySampleDelegates);
sample.Invoke("Parameter X");
Console.ReadLine();
}
}
public class DelegateClass {
public void MySampleMethodA(string zParameter) {
Console.WriteLine("MySampleMethodA. Parameter : {0}", zParameter);
}
public void MySampleMethodB(string zParameter) {
Console.WriteLine("MySampleMethodB. Parameter : {0}", zParameter);
}
public void MySampleMethodC(string zParameter) {
Console.WriteLine("MySampleMethodC. Parameter : {0}", zParameter);
}
}
}
An when you run the application, you will get the following output:
My passion lies in building business intelligence and data-based solutions, writing about things I work with and talking about it. New technologies relevant to my line of work interest me and I am often seen playing with early releases of such technologies.
My current role involves architecting and building a variety of data solutions, providing database maintenance and administration support, building the organization’s data practice, and training and mentoring peers.
My aspiration over the next several years is to achieve higher competency and recognition in the field of Data Analytics and move into a career of data science.
Specialities: SQL Server, T-SQL Development, SQL Server Administration, SSRS, SSIS, C#, ASP.Net, Crystal Reports