Multicast Delegates in C#


In my previous article we discuss about what is delegate and the advantages of delegates in C#. In this article we discuss about Multicast delegates in C# with example. Multicast is nothing but a delegate which invokes the multiple methods at same time. That means single delegate points to multiple methods. We will discuss about multicast delegate with simple example.

Open Microsoft Visual Studio 2015 => Create Windows Application and name it as CSharpMultiCastDelegate. Add Employee class with simple method GetEmployeeDetails() and exception logging class Log.cs as shown below.

Log.cs

using System;

 

namespace CSharpMultiCastDelegate

{

    public class Log

    {

        public static void LogExceptionInSQL(Exception ex)

        {

            //Logic to log exception in SQL

        }

 

        public static void LogExceptionInXML(Exception ex)

        {

            //Logic to log exception in XML

        }

 

        public static void LogExceptionInEventViewer(Exception ex)

        {

            //Logic to log exception in Event Viewer

        }

    }

}

 

Employee.cs

using System;

 

namespace CSharpMultiCastDelegate

{

    public class Employee

    {

        public int EmpId { get; set; }

        public string EmpName { get; set; }

 

        public void GetEmployeeDetails()

        {

            try

            {

                //Logic to get the Employee details

            }

            catch (Exception ex)

            {

                Log.LogExceptionInSQL(ex);

                Log.LogExceptionInXML(ex);

                Log.LogExceptionInEventViewer(ex);

            }

        }

    }

}

 

As shown below we are calling the Employee class GetEmployeeDetails().

using System;

using System.Windows.Forms;

 

namespace CSharpMultiCastDelegate

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

        private void Form1_Load(object sender, EventArgs e)

        {

            Employee objEmp = new Employee() { EmpId = 100, EmpName = "Mark" };

            objEmp.GetEmployeeDetails();

        }      

    }

}

 

As shown above Log class has three different methods to log exception in three different sources SQL, XML file, and in Event Viewer. Here we didn’t included the logic to log the exception as our focus is on multicast delegates. In Employee class GetEmployeeDetails() method catch block we are calling the three methods of Log class to log the exception. In future if you add one more source to log the exception in Log.cs class you have to include that method again in GetEmployeeDetails() method. To avoid this we can use multicast delegates as shown below.

Employee.cs

using System;

 

namespace CSharpMultiCastDelegate

{

    public class Employee

    {

        public int EmpId { get; set; }

        public string EmpName { get; set; }

 

        public void GetEmployeeDetails(LogDel del)

        {

            try

            {

                //Logic to get the Employee details

            }

            catch (Exception ex)

            {

                del(ex);

            }

        }

    }

}

 

using System;

using System.Windows.Forms;

 

namespace CSharpMultiCastDelegate

{

    public delegate void LogDel(Exception ex);

 

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

       

        private void Form1_Load(object sender, EventArgs e)

        {

            Employee objEmp = new Employee() { EmpId = 100, EmpName = "Mark" };

 

            LogDel del = new LogDel(Log.LogExceptionInSQL);

            del += new LogDel(Log.LogExceptionInXML);

            del += new LogDel(Log.LogExceptionInEventViewer);

 

            objEmp.GetEmployeeDetails(del);

        }      

    }

}

 

As shown above we created the delegate LogDel with same signature of Log.cs class methods. We are passing the this delegate to GetEmployeeDetails() method of Employee class. In future if you add new method to log exception you just have to add that method to delegate LogDel delegate before passing it to GetEmployeeDetails() methods. Here LogDel delegate pointing to three methods, so it is called as multicast delegate. Methods in multicast delegate invoked in the same order as they added. That means in the above example first LogExceptionInSQL() method will called, then LogExceptionInXML() method and finally LogExceptionInEventViewer() method will get called.

In the above example all the three methods are void type that means these methods will not return any value. For example if the Log.cs class methods returns string type as shown below, delegate will return only last method value.

using System;

 

namespace CSharpMultiCastDelegate

{

    public class Employee

    {

        public int EmpId { get; set; }

        public string EmpName { get; set; }

 

        public string GetEmployeeDetails(LogDel del)

        {

            try

            {

                int n1 = 1;

                int n2 = n1 / 0;

                //Logic to get the Employee details

                return "Success";

            }

            catch (Exception ex)

            {

                return del(ex);

            }

        }

    }

}

 

using System;

 

namespace CSharpMultiCastDelegate

{

    public class Log

    {

        public static string LogExceptionInSQL(Exception ex)

        {

            //Logic to log exception in SQL

            return "LogExceptionInSQL";

        }

 

        public static string LogExceptionInXML(Exception ex)

        {

            //Logic to log exception in XML

            return "LogExceptionInXML";

        }

 

        public static string LogExceptionInEventViewer(Exception ex)

        {

            //Logic to log exception in Event Viewer

            return "LogExceptionInEventViewer";

        }

    }

}

 

using System;

using System.Windows.Forms;

 

namespace CSharpMultiCastDelegate

{

    public delegate string LogDel(Exception ex);

 

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

       

        private void Form1_Load(object sender, EventArgs e)

        {

            Employee objEmp = new Employee() { EmpId = 100, EmpName = "Mark" };

 

            LogDel del = new LogDel(Log.LogExceptionInSQL);

            del += new LogDel(Log.LogExceptionInXML);

            del += new LogDel(Log.LogExceptionInEventViewer);

 

            MessageBox.Show(objEmp.GetEmployeeDetails(del));

        }      

    }

}

 

The above code returns message from LogExceptionInEventViewer() method only as shown below because LogExceptionInEventViewer() is the last method in the delegate LogDel.

If you want to get all methods return value you have to use GetInvocationList() method of delegate in GetEmployeeDetails() method catch block as shown below.

public List<string> GetEmployeeDetails(LogDel del)

{

            try

            {

                int n1 = 1;

                int n2 = n1 / 0;

                //Logic to get the Employee details

                List<string> strs = new List<string>();

                strs.Add("Success");

                return strs;

            }

            catch (Exception ex)

            {

                List<string> strs = new List<string>();

                foreach (LogDel del1 in del.GetInvocationList())

                {

                    strs.Add(del1(ex));

                }

                return strs;

            }

}

As shown above GetEmployeeDetails() method returns List of string type wwhich contains return values from all methods in delegate LogDel. Call GetEmployeeDetails() method and display return value as shown below.

private void Form1_Load(object sender, EventArgs e)

{

            Employee objEmp = new Employee() { EmpId = 100, EmpName = "Mark" };

 

            LogDel del = new LogDel(Log.LogExceptionInSQL);

            del += new LogDel(Log.LogExceptionInXML);

            del += new LogDel(Log.LogExceptionInEventViewer);

 

            List<string> strs= objEmp.GetEmployeeDetails(del);

 

            foreach (string str in strs)

            {

                MessageBox.Show(str);

            }

}      


We will get the return values in the same order as we add the methods to the multicast delegate LogDel.

                                                                                                                             

                                                                                                            CSharpMultiCastDelegateExp.zip (55.5KB)