Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multicast delegate and event

I am studying about delegates. Few days back, I did a sample for a multicast delegates and reviewed here My previous question and clearly understood about multicast delegate.

But now I trying to do a multicast delegate sample with a event. But I got some doubts while doing sample. In the above link, I did all functions and delegate declaration in one class and add the function in to delegate using += and just call the delegate. So all function inside delegate invoked.

But now I am doing it in two different classes and trying to do all functions with the help of a event. I am providing my current code below.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        ArithmeticOperations aOperations = new ArithmeticOperations();
        aOperations.StartCalculations += new ArithmeticOperations.BasicCalculations(aOperations_StartCalculations);
        aOperations.PerformCalculations(20, 10);
    }

    void aOperations_StartCalculations(string msg)
    {
        MessageBox.Show(msg);
    }
}


class ArithmeticOperations
{
    public delegate void BasicCalculations(string msg);

    public event BasicCalculations StartCalculations;


    public void PerformCalculations(int n1, int n2)
    {
        StartCalculations("Operation Success");
    }

    void Add(int num1, int num2)
    {
        MessageBox.Show("Performing addition.");
    }

    void Sub(int num1, int num2)
    {
        MessageBox.Show("Performing substraction.");
    }

    void Mul(int num1, int num2)
    {
        MessageBox.Show("Performing multiplication.");
    }

    void Div(int num1, int num2)
    {
        MessageBox.Show("Performing division.");
    }

}

Here in the Form1 is my main class and ArithmeticOperations class is using for doing functionalities. When on this statement

aOperations.PerformCalculations(20, 10);

in the Form1, the PerformCalculation() function in the ArithmeticOperations class will execute.

But my doubt is how I register all the Add, Sub, Mul and Div function to the delegate in ArithmeticOperations class to invoke all functions by just calling the delegate object and return "Operation Success" to the event callback function in Form1 class ?

like image 761
Arun Avatar asked Mar 05 '13 11:03

Arun


2 Answers

Since BasicCalculations takes a single argument of type string, it cannot be used to directly invoke your methods Add, Subtract etc.

If you want PerformCalculations to invoke each of your methods via multicast, you will need a delegate of a type equivalent to Action<int, int>, eg:

class ArithmeticOperations
{
    public delegate void BasicCalculations(string msg);

    public event BasicCalculations StartCalculations;

    private Action<int, int> calculations;

    public ArithmeticOperations()
    {
        this.calculations += this.Add;
        this.calculations += this.Sub;
    }

    public void PerformCalculations(int n1, int n2)
    {
        this.calculations.Invoke(n1, n2);
        StartCalculations("Operation Success");
    }

    // ...
}

If you want your individual arithmetic methods to invoke your StartCalculations event with a string, you can let them do it like this:

void Add(int num1, int num2)
{
    StartCalculations("Performing addition.");
}

When raising events, you should test that there are subscribers first (to avoid a NullReferenceException). The standard pattern is to get any handler subscribed, test for null then invoke the handler. This will avoid hitting a NullReferenceException, if someone unsubscribes after a testing the event for null:

void Add(int num1, int num2)
{
    var handler = this.StartCalculations;
    if (handler != null)
    {
        handler("Performing addition.");
    }
}

Since that would be a lot of code repetition for each method, you can refactor it into a separate method:

void Add(int num1, int num2)
{
    this.OnStartCalculation("Performing addition.");
}

void OnStartCalculation(string message)
{
    var handler = this.StartCalculations;
    if (handler != null)
    {
        handler(message);
    }
}
like image 105
Ergwun Avatar answered Nov 02 '22 07:11

Ergwun


one of the options would be creating a private event

  public delegate void BasicCalculations(string msg);

public delegate void DoMath(int na, int nb);
class ArithmeticOperations
{
    public ArithmeticOperations()
    {
        StartMath += new DoMath(ArithmeticOperations_StartMath);

    }

    void ArithmeticOperations_StartMath(int na, int nb)
    {
        Add(na, nb);
        Sub(na, nb);
        Mul(na, nb);
        Div(na,nb);
    }




    public event BasicCalculations StartCalculations;
    private event DoMath StartMath;

    public void PerformCalculations(int n1, int n2)
    {
        StartMath(n1, n2);
        StartCalculations("Operation Success");
    }

    void Add(int num1, int num2)
    {
        Console.WriteLine("Performing addition.");
    }

    void Sub(int num1, int num2)
    {
         Console.WriteLine("Performing substraction.");
    }

    void Mul(int num1, int num2)
    {
         Console.WriteLine("Performing multiplication.");
    }

    void Div(int num1, int num2)
    {
         Console.WriteLine("Performing division.");
    }

}
like image 29
TalentTuner Avatar answered Nov 02 '22 09:11

TalentTuner