Multicast Delegates must have a return type of void. Why?
Asked Answered
G

3

9

Multicast Delegates must have a return type of void Otherwise it will throw an exception.

I want to know whats the reason behind it, what if multiple methods could have a same return type as of a delegate ?

Garderobe answered 21/9, 2012 at 12:37 Comment(1)
Can you provide an example of where it throws an exception?Vulpine
V
35

The premise is wrong; it works fine:

Func<int> func = delegate { Console.WriteLine("first part"); return 5; };
func += delegate { Console.WriteLine("second part"); return 7; };
int result = func();

That is a multicast delegate with a non-void result, working fine. You can see from the console that both parts executed. The result of the last item is the one returned. We can demonstrate that this is a true multicast delegate:

if(func is MulticastDelegate) Console.WriteLine("I'm multicast");

and it will write "I'm multicast" even after just the first line (when there is only a single method listed).

If you need more control over individual results, then use GetInvocationList():

foreach (Func<int> part in func.GetInvocationList())
{
    int result = part();
}

which allows you to see each individual result.

In IL terminology:

.class public auto ansi sealed Func<+ TResult>
    extends System.MulticastDelegate`

which is to say: Func<T> inherits from MulticastDelegate. Basically, to all intents and purposes, all delegates in .NET are multicast delegates. You might be able to get a non-multicast delegate in managed C++, I don't know. But certainly not from C#.

Vulpine answered 21/9, 2012 at 12:45 Comment(1)
@Jon from memory, that might have been one of the big changes between .NET 1.0 and .NET 1.1Vulpine
H
4

The following answer is factually wrong, because you currently *can* have multicast delegates with non-void return type (the jury is still out regarding whether this has always been so). However, it does answer the question "Why might a language disallow such delegates?", so I am leaving it for completeness.

Now go and upvote Marc.


Because the multiple methods would return multiple values, so what should the one return value of the delegate be then? Clearly there is no answer that would be satisfying in all circumstances. You could argue that the multicast delegate should:

  • return the value of the first method in invocation order (but IIRC invocation order is unspecified, so how would this work?)
  • return the value of the last method, as above
  • return the single distinct value returned by all delegates; throw an exception if not all of them agree
Hilde answered 21/9, 2012 at 12:38 Comment(5)
It needs to be noted that all delegates in .NET are multi cast delegates.Quadrivium
@DanielHilgarth: Are you referring to the class name and the functionality it supports? If so, then technically you are correct but "all delegates are multicast" leaves the wrong impression. Obviously you can have delegates with non-void return type, and this needs to be reconciled with your statement.Hilde
See answer by Marc. That's exactly what I meant.Quadrivium
See Jon Skeet's article: "The difference between Delegate and MulticastDelegate is largely historical; in betas of .NET 1.0 the difference was significant (and annoying) - Microsoft considered merging the two types together, but decided it was too late in the release cycle to make such a major change. You can pretty much pretend that they're only one type."Vulpine
@MarcGravell: Thanks, I know that delegates are derived from MulticastDelegate as both Daniel's and your original comment revealed. However, I was under the mistaken impression that MulticastDelegate would not let you combine unless the return type was void.Hilde
K
4

in multicast the problem is that it override all values just print the last method value if it have return type,so you have to capture the return type of one by one,lets see the code below

 class Program
{
    // i am going to add and subtract two num but i wanna get result in string the same thing you can do for int and what ever you want
      delegate string mydeledagte(int a,int b);
      delegate string d(int s, int t);
    static void Main(string[] args)
    {
        mydeledagte ab = new mydeledagte(ad);
        mydeledagte d= new mydeledagte(sub);
        mydeledagte multi = ab + d;

        foreach (mydeledagte individualMI in multi.GetInvocationList())
        {
            string retVal = individualMI(3, 5);
            Console.WriteLine("Output: " + retVal);
            Console.WriteLine("\n***developer of KUST***");
            Console.ReadKey();
        }
    }
    static string ad(int a, int b)
    {

        return (a + b).ToString();

    }
    static string sub(int a, int b)
    {

        return (a - b).ToString(); ;
    }
}
Khan answered 30/1, 2015 at 5:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.