Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multicast delegate of type Func (with return value)?

Tags:

c#

.net

I have the following code:

Func<string, string> func1 = (param) =>
{
    Console.WriteLine("Func 1 executing");
    return "Hello" + param;
};
Func<string, string> func2 = (param) =>
{
    Console.WriteLine("Func 2 executing");
    return "World" + param;
};
Func<string, string> funcSum = func1 + func2;
string funcResult = funcSum("!");
Console.WriteLine(funcResult);

The output is:

Func 1 executing
Func 2 executing
World!

Inverting the sum:

Func<string, string> funcSum = func2 + func1;

Gives the output:

Func 2 executing
Func 1 executing
Hello!

My initial test was done with a boolean return type, and the returned value was also always determined by the last function. Is it working as intended? Aren't we losing the return value of the other functions? If so, is there a use case in real world of those multicast delegate of functions?

like image 911
David Khuu Avatar asked Jun 01 '14 17:06

David Khuu


People also ask

What should be the return type of multicast delegate methods?

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

What is multicast delegate explain with example?

The multicast delegate contains a list of the assigned delegates. When the multicast delegate is called, it invokes the delegates in the list, in order. Only delegates of the same type can be combined. The - operator can be used to remove a component delegate from a multicast delegate.

What is the return type of delegate?

delegate: It is the keyword which is used to define the delegate. return_type: It is the type of value returned by the methods which the delegate will be going to call. It can be void. A method must have the same return type as the delegate.

Can delegate return a value?

If you have a method that accepts two numbers and you want to add them and return the sum of the two numbers, you can use a delegate to store the return value of the method as shown in the code snippet given below.


2 Answers

Is it working as intended?

It's working as specified, at least. Whether that's what you intended or not is a different matter :) From section 15.4 of the C# 5 specification - emphasis mine:

Invocation of a delegate instance whose invocation list contains multiple entries proceeds by invoking each of the methods in the invocation list, synchronously, in order. Each method so called is passed the same set of arguments as was given to the delegate instance. If such a delegate invocation includes reference parameters (§10.6.1.2), each method invocation will occur with a reference to the same variable; changes to that variable by one method in the invocation list will be visible to methods further down the invocation list. If the delegate invocation includes output parameters or a return value, their final value will come from the invocation of the last delegate in the list.

Next:

Aren't we losing the return value of the other functions?

Yes, at the moment.

If so, is there a use case in real world of those multicast delegate of functions?

Very rarely, to be honest. However, you can split a multicast delegate apart, using Delegate.GetInvocationList():

foreach (Func<string, string> func in funcSum.GetInvocationList())
{
    Console.WriteLine(func("!"));
}
like image 133
Jon Skeet Avatar answered Oct 16 '22 14:10

Jon Skeet


The multicast delegate will always return the result of the last function. Because there is no predefined way to combine or chain the T results.

If you want to obtain all the results along the chain, try this :

    var result = "!";
    foreach (Func<string, string> func in funcSum.GetInvocationList())
    {
        result = func(result);
    }
like image 32
Xiaoy312 Avatar answered Oct 16 '22 12:10

Xiaoy312