ุงู„ู€ Delegate ู‡ูˆ (Type-Safe Function Pointer). ุฏู‡ ู…ุนู†ุงู‡ ุฅู† ุงู„ู€ delegate ุจูŠุจู‚ุง ุฌูˆุงู‡ reference ู„ู€ method ุฃูˆ function ูˆู„ู…ุง ุจู†ุณุชุฏุนูŠ ุงู„ู€ delegateุŒ ุงู„ู€ method ุงู„ู„ูŠ ุจูŠุดุงูˆุฑ ู„ูŠู‡ุง ุจุชุชู†ูุฐ.

ุงู„ู€ delegate signature ูˆุงู„ู€ method ุงู„ู„ูŠ ุจูŠุดุงูˆุฑ ุนู„ูŠู‡ุง ู„ุงุฒู… ูŠูƒูˆู† ู„ูŠู‡ู… ู†ูุณ ุงู„ู€ signature.

ููŠู‡ ู†ูˆุนูŠู† ู…ู† ุงู„ู€ Delegates ููŠ C#:

  • ุงู„ู€ Single Cast Delegate: ุงู„ู€ Delegate ุจูŠุดูŠุฑ ู„ู€ function ุฃูˆ method ูˆุงุญุฏุฉ ุจุณ.
  • ุงู„ู€ Multicast Delegate: ุงู„ู€ Delegate ุจูŠุดูŠุฑ ู„ุฃูƒุชุฑ ู…ู† function ุฃูˆ method.

ุงุชูƒู„ู…ู†ุง ุจุงู„ูุนู„ ุนู† Singlecast Delegate. ุงู„ู†ู‡ุงุฑุฏู‡ุŒ ู‡ู†ุชูƒู„ู… ุนู† Multicast Delegates.

What is Multicast Delegate in C#?

ุงู„ู€ Multicast Delegate ููŠ C# ู‡ูˆ delegate ุจูŠุญู…ู„ references ู„ุฃูƒุชุฑ ู…ู† handler function ูˆุงุญุฏุฉ. ู„ู…ุง ุจู†ุณุชุฏุนูŠ multicast delegateุŒ ูƒู„ ุงู„ู€ functions ุงู„ู„ูŠ ุงู„ู€ delegate ุจูŠุดูŠุฑ ู„ูŠู‡ุง ุจุชุชู†ูุฐ. ู„ูˆ ุนุงูŠุฒ ุชุณุชุฏุนูŠ ุฃูƒุชุฑ ู…ู† method ุจุงุณุชุฎุฏุงู… delegateุŒ ูŠุจู‚ู‰ ูƒู„ ุงู„ู€ method signatures ู„ุงุฒู… ุชูƒูˆู† ุฒูŠ ุจุนุถ.

ูู€ multicast delegate ู‡ูˆ ู…ุฌุฑุฏ (array) ู…ู† ุฃูƒุชุฑ ู…ู† pipeline ุฃูˆ ุฃูƒุชุฑ ู…ู† delegate. ุงู„ู€ Delegates ุจุชุชู†ูุฐ ุจู†ูุณ ุงู„ุชุฑุชูŠุจ ุงู„ู„ูŠ ุงุชุญุทุช ุจูŠู‡ ููŠ ุงู„ู€ invocation list. ุงู„ู€ InvocationList ู‡ูˆ ุจุจุณุงุทุฉ Array ู…ู† delegates ุฃูˆ pipelines ูƒู„ pipeline ููŠู‡ุง ุจูŠู†ู‚ู„ ุงู„ุจูŠุงู†ุงุช ู„ู€ method ู…ุฎุชู„ูุฉ.

Example to Understand Multicast Delegate in C#

ู…ู† ุบูŠุฑ delegates.

using System;
namespace MulticastDelegateDemo
{
    public class Rectangle
    {
        public void GetArea(double Width, double Height)
        {
            Console.WriteLine($"Area is {Width * Height}");
        }
        public void GetPerimeter(double Width, double Height)
        {
            Console.WriteLine($"Perimeter is {2 * (Width + Height)}");
        }
        static void Main(string[] args)
        {
            Rectangle rect = new Rectangle();
            rect.GetArea(23.45, 67.89);
            rect.GetPerimeter(23.45, 67.89);
            Console.ReadKey();
        }
    }
}

Output:

Area is 1592.1205
Perimeter is 182.68

ููŠ ุงู„ู…ุซุงู„ ุงู„ู„ูŠ ููˆู‚ุŒ ุนู…ู„ู†ุง instance ู…ู† Rectangle class ูˆุจุนุฏูŠู† ุงุณุชุฏุนูŠู†ุง ุงู„ุงุชู†ูŠู† methods. ุฏู„ูˆู‚ุชูŠ ุฃู†ุง ุนุงูŠุฒ ุฃุนู…ู„ delegate ูˆุงุญุฏ ูŠุณุชุฏุนูŠ ุงู„ุงุชู†ูŠู† methods ุงู„ู„ูŠ ููˆู‚ ุฏูˆู„. ุงู„ุงุชู†ูŠู† methods ู„ูŠู‡ู… ู†ูุณ ุงู„ู€ signature ุจุฃุณู…ุงุก ู…ุฎุชู„ูุฉุŒ ูู†ู‚ุฏุฑ ู†ุนู…ู„ delegate ูˆุงุญุฏ ูŠุญู…ู„ ุงู„ู€ reference ุจุชุงุน ุงู„ุงุชู†ูŠู† methods. ูˆู„ู…ุง ู†ุณุชุฏุนูŠ ุงู„ู€ delegateุŒ ู‡ูŠุณุชุฏุนูŠ ุงู„ุงุชู†ูŠู† methods. ูˆุฏู‡ ุงู„ู„ูŠ ุจูŠุชุณู…ู‰ Multicast Delegate.

Multicast Delegate Example in C#

using System;
namespace MulticastDelegateDemo
{
    public delegate void RectangleDelegate(double Width, double Height);
    public class Rectangle
    {
        public void GetArea(double Width, double Height) { /* ... */ }
        public void GetPerimeter(double Width, double Height) { /* ... */ }
 
        static void Main(string[] args)
        {
            Rectangle rect = new Rectangle();
            RectangleDelegate rectDelegate = new RectangleDelegate(rect.GetArea);
 
            // Use += operator to chain delegates together.
            rectDelegate += rect.GetPerimeter;
 
            Delegate[] InvocationList = rectDelegate.GetInvocationList();
            Console.WriteLine("InvocationList:");
            foreach (var item in InvocationList)
            {
                Console.WriteLine($"  {item}");
            }
            Console.WriteLine();
            Console.WriteLine("Invoking Multicast Delegate:");
            rectDelegate(23.45, 67.89);
 
            Console.WriteLine();
            Console.WriteLine("Invoking Multicast Delegate After Removing one Pipeline:");
            // Removing a method from delegate object
            rectDelegate -= rect.GetPerimeter;
            rectDelegate.Invoke(13.45, 76.89);
 
            Console.ReadKey();
        }
    }
}

Output:

InvocationList:
  MulticastDelegateDemo.RectangleDelegate
  MulticastDelegateDemo.RectangleDelegate

Invoking Multicast Delegate:
Area is 1592.1205
Perimeter is 182.68

Invoking Multicast Delegate After Removing one Pipeline:
Area is 1034.1205

ููŠ ุงู„ู…ุซุงู„ ุงู„ู„ูŠ ููˆู‚ุŒ ุนู…ู„ู†ุง delegate ูˆุงุญุฏ ุงู„ู€ signature ุจุชุงุนู‡ ู‡ูˆ ู‡ูˆ ู†ูุณ ุจุชุงุน ุงู„ุงุชู†ูŠู† methods GetArea , GetPerimeter.

ุจุนุฏูŠู† ุนู…ู„ู†ุง instance ู…ู† delegate ูˆุฑุจุทู†ุง ุงู„ุงุชู†ูŠู† methods ุจุงุณุชุฎุฏุงู… += operator.

ุจู†ูุณ ุงู„ุทุฑูŠู‚ุฉุŒ ุชู‚ุฏุฑ ุชุณุชุฎุฏู… -= operator ุนุดุงู† ุชุดูŠู„ function ู…ู† ุงู„ู€ delegate.

ุจู…ุฌุฑุฏ ู…ุง ุจู†ุฑุจุท ุงู„ุงุชู†ูŠู† methods ุจุงู„ู€ delegate instance ูˆู„ู…ุง ุจู†ุณุชุฏุนูŠ ุงู„ู€ delegateุŒ ุงู„ุงุชู†ูŠู† methods ุจูŠุชู†ูุฐูˆุง.

Another Approach to Creating Multicast Delegates in C#

using System;
namespace MulticastDelegateDemo
{
    public delegate void MathDelegate(int No1, int No2);
    public class Program
    {
        // Static Methods
        public static void Add(int x, int y) { /*...*/ }
        public static void Sub(int x, int y) { /*...*/ }
        
        // Non-Static Methods
        public void Mul(int x, int y) { /*...*/ }
        public void Div(int x, int y) { /*...*/ }
 
        static void Main(string[] args)
        {
            Program p = new Program();
            MathDelegate del1 = new MathDelegate(Add);
            MathDelegate del2 = new MathDelegate(Program.Sub);
            MathDelegate del3 = new MathDelegate(p.Mul); 
            MathDelegate del4 = new MathDelegate(p.Div);
 
            // Use + operator to chain delegates together
            MathDelegate del5 = del1 + del2 + del3 + del4;
 
            Console.WriteLine("Invoking Multicast Delegate::");
            del5.Invoke(20, 5);
 
            Console.WriteLine();
            Console.WriteLine("Invoking Multicast Delegate After Removing one Delegate:");
            del5 -= del2;
            del5(22, 7);
            
            Console.ReadKey();
        }
    }
}

ู‡ู†ุง ุงุณุชุฎุฏู…ู†ุง static ูˆ non-static methods. ุนู…ู„ู†ุง ุฃุฑุจุนุฉ instances ู…ู† ุงู„ู€ delegate ูˆุฑุจุทู†ุง ุงู„ุฃุฑุจุน methods. ููŠ ุงู„ุขุฎุฑุŒ ุนู…ู„ู†ุง delegate instance ุฎุงู…ุณ ูˆุฑุจุทู†ุง ุจูŠู‡ ูƒู„ ุงู„ุฃุฑุจุน delegate instances ุจุงุณุชุฎุฏุงู… + operator. ุฏู„ูˆู‚ุชูŠุŒ ุงู„ู€ delegate ุงู„ุฎุงู…ุณ ุจู‚ู‰ multicast delegate.

Multicast Delegates with Return Type in C#

ุงู„ู€ multicast delegate ุจูŠุณุชุฏุนูŠ ุงู„ู€ methods ุจู†ูุณ ุงู„ุชุฑุชูŠุจ ุงู„ู„ูŠ ุงุชุถุงูุช ุจูŠู‡. ู„ุญุฏ ุฏู„ูˆู‚ุชูŠุŒ ุงู„ุฃู…ุซู„ุฉ ุงู„ู„ูŠ ู†ุงู‚ุดู†ุงู‡ุง ู…ูƒุงู†ุชุด ุจุชุฑุฌุน ุฃูŠ ุญุงุฌุฉ (void). ุฅูŠู‡ ุงู„ู„ูŠ ุจูŠุญุตู„ ู„ูˆ ุงู„ู€ delegate ู„ูŠู‡ return typeุŸ

ู„ูˆ ุงู„ู€ delegate ู„ูŠู‡ return type ุบูŠุฑ voidุŒ ูˆู„ูˆ ุงู„ู€ delegate ุฏู‡ multicast delegateุŒ ูŠุจู‚ู‰ ุจุณ ู‚ูŠู…ุฉ ุขุฎุฑ method ุชู… ุงุณุชุฏุนุงุคู‡ุง ู‡ูŠ ุงู„ู„ูŠ ู‡ุชุฑุฌุน.

ุจู†ูุณ ุงู„ู…ู†ุทู‚ุŒ ู„ูˆ ุงู„ู€ delegate ู„ูŠู‡ out parameterุŒ ูู‚ูŠู…ุฉ ุงู„ู€ output parameter ู‡ุชูƒูˆู† ุงู„ู‚ูŠู…ุฉ ุงู„ู„ูŠ ุฎุตุตุชู‡ุง ุขุฎุฑ method ุชู… ุงุณุชุฏุนุงุคู‡ุง ู…ู† ุงู„ู€ Invocation List.

Example to Understand Multicast Delegates with Return Type

using System;
namespace MulticastDelegateDemo
{
    // Delegate's return type is int
    public delegate int SampleDelegate();
    public class Program
    {
        static void Main()
        {
            SampleDelegate del = new SampleDelegate(MethodOne);
            del += MethodTwo;
            
            // The value returned will be 2, from MethodTwo()
            int ValueReturnedByDelegate = del();
            Console.WriteLine($"Returned Value = {ValueReturnedByDelegate}");
            Console.ReadKey();
        }
        public static int MethodOne()
        {
            Console.WriteLine("MethodOne is Executed");
            return 1;
        }
        public static int MethodTwo()
        {
            Console.WriteLine("MethodTwo is Executed");
            return 2;
        }
    }
}

Output:

MethodOne is Executed
MethodTwo is Executed
Returned Value = 2

Example to Understand Multicast Delegates using out Parameter in C#

using System;
namespace MulticastDelegateDemo
{
    // Delegate has an int output parameter
    public delegate void SampleDelegate(out int Integer);
    public class Program
    {
        static void Main()
        {
            SampleDelegate del = new SampleDelegate(MethodOne);
            del += MethodTwo;
            
            // The value of ValueFromOutPutParameter will be 2
            int ValueFromOutPutParameter = -1;
            del(out ValueFromOutPutParameter);
            Console.WriteLine($"Returned Value = {ValueFromOutPutParameter}");
            Console.ReadKey();
        }
        public static void MethodOne(out int Number)
        {
            Console.WriteLine("MethodOne is Executed");
            Number = 1;
        }
        public static void MethodTwo(out int Number)
        {
            Console.WriteLine("MethodTwo is Executed");
            Number = 2;
        }
    }
}

Output:

MethodOne is Executed
MethodTwo is Executed
Returned Value = 2