C# Func类型的多播委托(带返回值)?

C# Func类型的多播委托(带返回值)?,c#,.net,C#,.net,我有以下代码: 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" + pa

我有以下代码:

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);
将总和倒置:

Func<string, string> funcSum = func2 + func1;
我的初始测试是使用布尔返回类型完成的,返回值也总是由最后一个函数确定。它是否按预期工作?我们不是失去了其他函数的返回值吗?如果是这样的话,在现实世界中是否存在这些函数的多播委托的用例

它是否按预期工作

至少它是按照规定工作的。这是否是您的意图是另一回事:)与C#5规范第15.4节-重点矿山不同:

通过按顺序同步调用调用列表中的每个方法,调用其调用列表包含多个条目的委托实例。每个被调用的方法被传递给委托实例的参数集相同。如果此类委托调用包括引用参数(§10.6.1.2),则每次方法调用都将引用同一变量;调用列表中的一个方法对该变量所做的更改将对调用列表后面的方法可见如果委托调用包含输出参数或返回值,则其最终值将来自列表中最后一个委托的调用。

下一步:

我们不是失去了其他函数的返回值吗

是的,现在

如果是这样的话,在现实世界中是否存在这些函数的多播委托的用例

老实说,很少。但是,可以使用以下方法拆分多播委托:

foreach(funcSum.GetInvocationList()中的Func Func)
{
控制台写入线(func(“!”);
}

多播委托将始终返回最后一个函数的结果。因为没有预定义的方法来组合或链接
T
结果

如果要获得链上的所有结果,请尝试以下操作:

    var result = "!";
    foreach (Func<string, string> func in funcSum.GetInvocationList())
    {
        result = func(result);
    }
var result=“!”;
foreach(funcSum.GetInvocationList()中的Func Func)
{
结果=func(结果);
}

您的大部分问题已经得到了回答,但缺少的一件事是这个问题的实际用例。这里有一个:异步事件处理程序

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)));
}
这允许类的用户简单地编写

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

但该对象仍将确保
OnX
的任务在事件处理程序完成之前不会完成。

多播委托对事件至关重要,而且
Func
可能支持一致性?@Yoga:我没有说多播委托毫无意义-我同意这样的假设,即在现实世界中,函数的多播委托(非无效委托)很少。传统的事件模式使用void委托类型。请注意,委托组合完全早于Func。。。但是,是的,组合的非无效委托的效果基本上是为了一致性。而且你可以从中得到一些信息,毕竟……老实说,如果有人问我一个更好的解决方案,我将无法给出一个答案,或者是一个有着丰富理性的替代方案。此外,我们谈论的是微软和一个专业团队,所以我不反对这一点(没有讽刺意味)。Dupe:
    var result = "!";
    foreach (Func<string, string> func in funcSum.GetInvocationList())
    {
        result = func(result);
    }
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)));
}
myobject.X += async (sender, e) => { ... };