Search code examples
c#delegatesinvokemulticastdelegate

Multicast delegate with double return type, only returns the last method's result, and not All method's results


I am new to this topic and wanted to know is there a way that I could get all method's result and not only the last method's result while using a return type for multicast delegate?

Here is my code:

class Program
    {
        public delegate double rectangleDelegate (double Width, double Heigth);
        class Rectangle
        {
            public double GetPerimeter(double Width, double Heigth)
            {
                return 2 * (Width + Heigth);
            }
            public double GetArea(double Width, double Heigth)
            {
                return Width * Heigth;
            }
        }
        static void Main(string[] args)
        {
            Rectangle rectangle = new Rectangle();

            rectangleDelegate obj = rectangle.GetArea;
            obj += rectangle.GetPerimeter;

            Console.WriteLine(obj(4, 2));

        }
    }

I tried with void for my methods and delegates and printing the results. In this case I could see both methods output on console. But when using a return type like double I only get last methods output.

Can I do something to get each method's return and store it in a variable or a list? Or is it totally wrong approach to expect such a thing from multicast delegates?


Solution

  • You can't get all of the return values like this. The only way I know to do it is a little hacky uses GetInvocationList:

    rectangleDelegate obj = rectangle.GetArea;
    obj += rectangle.GetPerimeter;
    
    foreach(var del in obj.GetInvocationList())
    {
        var result = (double)del.DynamicInvoke(4, 2);
        Console.WriteLine(result);
    }
    

    Of course, this is a little dangerous as it assumes the delegates of a specific format. You could coerce the delegate to the type you use like this, which means you don't need to use DynamicInvoke:

    foreach(rectangleDelegate del in obj.GetInvocationList())
    {
        var result = del(4, 2);
        Console.WriteLine(result);
    }
    

    Or a safer version:

    foreach(var del in obj.GetInvocationList().OfType<rectangleDelegate>())
    {
        var result = del(4, 2);
        Console.WriteLine(result);
    }