Multicast delegate of type Func (with return value)?

前端 未结 3 1790
粉色の甜心
粉色の甜心 2020-12-01 23:53

I have the following code :

Func func1 = (param) =>
{
    Console.WriteLine(\"Func 1 executing\");
    return \"Hello\" + param;
};
         


        
相关标签:
3条回答
  • 2020-12-02 00:37

    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);
        }
    
    0 讨论(0)
  • 2020-12-02 00:40

    Most of your question has been answered already, but one thing that's missing is a real-world use case for this. Here's one: asynchronous event handlers.

    public delegate Task AsyncEventHandler(object sender, EventArgs e);
    public event AsyncEventHandler X;
    public async Task OnX(EventArgs e) {
      // ...
    
      var @event = X;
      if (@event != null)
        await Task.WhenAll(
          Array.ConvertAll(
            @event.GetInvocationList(),
            d => ((AsyncEventHandler)d)(this, e)));
    }
    

    This allows the user of the class to simply write

    myobject.X += async (sender, e) => { ... };
    

    but the object will still ensure that OnX's task doesn't complete until the event handler's has.

    0 讨论(0)
  • 2020-12-02 00:48

    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("!"));
    }
    
    0 讨论(0)
提交回复
热议问题