Func类型的多播委托(具有返回值)?
我有以下代码:
Func func1 = (param) => { Console.WriteLine("Func 1 executing"); return "Hello" + param; }; Func func2 = (param) => { Console.WriteLine("Func 2 executing"); return "World" + param; }; Func funcSum = func1 + func2; string funcResult = funcSum("!"); Console.WriteLine(funcResult);
输出是:
Func 1 executing Func 2 executing World!
反转总和:
Func funcSum = func2 + func1;
给出输出:
Func 2 executing Func 1 executing Hello!
我的初始测试是使用布尔返回类型完成的,返回的值也始终由最后一个函数确定。 它是按预期工作的吗? 我们不是在失去其他function的回报价值吗? 如果是这样,那些function的多播委托在现实世界中是否存在用例?
它是按预期工作的吗?
它至少按照规定工作。 这是不是你想要的是另一回事:)从C#5规范的第15.4节 – 强调我的:
通过按顺序同步调用调用列表中的每个方法来调用其调用列表包含多个条目的委托实例。 所谓的每个方法都传递给委托实例的同一组参数。 如果这样的委托调用包含引用参数(第10.6.1.2节),则每个方法调用都将引用同一个变量; 通过调用列表中的一个方法对该变量的更改将对调用列表中的下一个方法可见。 如果委托调用包括输出参数或返回值,则它们的最终值将来自列表中最后一个委托的调用。
下一个:
我们不是在失去其他function的回报价值吗?
是的,此刻。
如果是这样,那些function的多播委托在现实世界中是否存在用例?
说实话,很少。 但是,您可以使用Delegate.GetInvocationList()
拆分多播委托:
foreach (Func func in funcSum.GetInvocationList()) { Console.WriteLine(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
的任务在事件处理程序具有之前不会完成。
多播委托将始终返回最后一个函数的结果。 因为没有预定义的方法来组合或链接T
结果。
如果您想获得链中的所有结果,请尝试以下方法:
var result = "!"; foreach (Func func in funcSum.GetInvocationList()) { result = func(result); }