Introduction
In this article, we look at delegates and how to multicast them.
Before we understand delegates, we need to know some of the basic stuff, such as the Reference type variable, which holds the reference of memory address instead of value.
Example
Person objPerson = new Person();
Here, objPerson is a reference variable that is pointing towards the Person's object.
We know that we can hold the reference of an object, but how cool it would be if we can hold a reference to a method.
That's where delegate comes into the picture.
A delegate holds a reference to the methods, kind of a function pointer in C++.
What is the Purpose for using Delegates?
The answer is to ensure which method is to be called when an event is triggered plus the reference can be changed at runtime.
Enough talk: let's see its syntax.
There are 3 steps involved.
Declaration of Delegate
syntax
Syntac - <Access-Modifier> delegate <return type> <delegate-name> <parameter list>
//Step 1 : Declaring a delegate
public delegate int MyDelegate (string s);
Create Delegate Instances
//Step 2 : Creating a delegate instances
CheckSmartPhone isThisSmartPhone = new CheckSmartPhone(GetIPhoneX);
Invoking a method through the delegate instance
//Step 3 : calling the methods using the delegate objects
bool checkSmartPhone = isThisSmartPhone("IPhoneX");
Here, GetIPhoneX is a Method, which must match exact same signature as defined in the delegate's declaration.
private static bool GetIPhoneX(string name)
{
if (name == "IPhoneX")
return true;
else
return false;
}
Note. Static is only because we are going to call this method inside the Main method.
Complete Source Code
class Program
{
//Step 1 : Declaring a delegate
public delegate bool CheckSmartPhone(string smartPhoneName);
static void Main(string[] args)
{
//Step 2 : Creating a delegate instances
CheckSmartPhone isThisSmartPhone = new CheckSmartPhone(GetIPhoneX);
//Step 3 : calling the methods using the delegate objects
bool checkSmartPhone = isThisSmartPhone("IPhoneX");
if (checkSmartPhone)
{
System.Console.WriteLine("It is a smart phone!!!");
}
else
{
System.Console.WriteLine("It is not a smart phone!!!");
}
}
private static bool GetIPhoneX(string name)
{
if (name == "IPhoneX")
return true;
else
return false;
}
}
Output
Now let's see the Multicasting of a Delegate.
Delegate objects can be composed using the "+" operator and decomposed with "-" operator.
Only delegates with the same signature can be composed together,i.e. the same Delegate but different instances can be composed together.
Let's understand this with code.
We will check if smartPhones runs on "IOS" or not.
Rather than calling each method separately, we can simply have 2 delegate instances and concatenating them together.
Here are our two methods, which checks which OS their smartPhone runs on.
private static bool GetIPhoneX(string OS)
{
if (OS == "IOS")
return true;
else
return false;
}
private static bool GetOnePlus8(string OS)
{
if (OS == "Android")
return true;
else
return false;
}
//Step 1 : Declaring a delegate
public delegate bool CheckSmartPhone(string OSName);
//Step 2 : Creating a delegate instances
CheckSmartPhone areBothRunsOnApple = new CheckSmartPhone(GetIPhoneX);
CheckSmartPhone onePlus8 = new CheckSmartPhone(GetOnePlus8);
//concatenating delegate instances
areBothRunsOnApple += onePlus8;
//Step 3 : calling the methods using the delegate objects
bool check_IOS_Devices = areBothRunsOnApple("IOS");
if (check_IOS_Devices)
{
System.Console.WriteLine("Both runs on IOS!!!");
}
else
{
System.Console.WriteLine("Not all of them runs on IOS!!!");
}
Not all of them run on iOS since one of them runs on Android!
Let's see another iPhone and check if that works.
private static bool GetIphoneXR(string OS)
{
if (OS == "IOS")
return true;
else
return false;
}
Also make respective changes,
//Step 2 : Creating a delegate instances
CheckSmartPhone areBothRunsOnApple = new CheckSmartPhone(GetIPhoneX);
CheckSmartPhone IphoneXR = new CheckSmartPhone(GetIphoneXR);
//concatenating delegate instances
areBothRunsOnApple += IphoneXR;
//Step 3 : calling the methods using the delegate objects
bool check_IOS_Devices = areBothRunsOnApple("IOS");
if (check_IOS_Devices)
{
System.Console.WriteLine("Both runs on IOS!!!");
}
else
{
System.Console.WriteLine("Not all of them runs on IOS!!!");
}
Outout
Perfect, it works.
In the same way, you can use minus operators to remove unwanted calls. Let's say our program needs android smartPhone but not in this delegate calls so you can simply remove that with "-" operator. so it won't call the GetOnePlus8 method.
namespace I_Cant_See_Sharp
{
class Program
{
//Step 1 : Declaring a delegate
public delegate bool CheckSmartPhone(string OSName);
static void Main(string[] args)
{
//Step 2 : Creating a delegate instances
CheckSmartPhone areBothRunsOnApple = new CheckSmartPhone(GetIPhoneX);
CheckSmartPhone IphoneXR = new CheckSmartPhone(GetIphoneXR);
CheckSmartPhone onePlus8 = new CheckSmartPhone(GetOnePlus8);
//concatenating delegate instances
areBothRunsOnApple += IphoneXR -= onePlus8;
//Step 3 : calling the methods using the delegate objects
bool check_IOS_Devices = areBothRunsOnApple("IOS");
if (check_IOS_Devices)
{
System.Console.WriteLine("Both runs on IOS!!!");
}
else
{
System.Console.WriteLine("Not all of them runs on IOS!!!");
}
}
private static bool GetIPhoneX(string OS)
{
if (OS == "IOS")
return true;
else
return false;
}
private static bool GetIphoneXR(string OS)
{
if (OS == "IOS")
return true;
else
return false;
}
private static bool GetOnePlus8(string OS)
{
if (OS == "Android")
return true;
else
return false;
}
}
}
It works just fine. Delegate call has removed GetOnePlus8 method call, & only check if IPhoneX & iPhone-XR are compatible with IOS.
Alright, so this is how you can use delegates in C#.
It's a beautiful concept and I hope this article has helped you to gain some insights into delegates behavior.
We will learn more about Func, Action & Predicate in the next article.