簡體   English   中英

Func 類型的多播委托(帶返回值)?

[英]Multicast delegate of type Func (with return value)?

我有以下代碼:

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 1 executing
Func 2 executing
World!

求和的倒數:

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

給出輸出:

Func 2 executing
Func 1 executing
Hello!

我最初的測試是用布爾返回類型完成的,返回值也總是由最后一個函數決定。 它是否按預期工作? 我們不是失去了其他函數的返回值嗎? 如果是這樣,那些函數的多播委托在現實世界中是否有用例?

它是否按預期工作?

它至少按規定工作。 這是否是您的意圖是另一回事:) 來自 C# 5 規范的第 15.4 節 - 強調我的:

調用一個委托實例,它的調用列表包含多個條目,它通過按順序同步調用調用列表中的每個方法來進行。 所調用的每個方法都傳遞給委托實例的相同參數集。 如果這樣的委托調用包含引用參數(第 10.6.1.2 節),則每次方法調用都將引用同一個變量; 調用列表中的一個方法對該變量的更改將對調用列表更下方的方法可見。 如果委托調用包含輸出參數或返回值,則它們的最終值將來自列表中最后一個委托的調用。

下一個:

我們不是失去了其他函數的返回值嗎?

是的,目前。

如果是這樣,那些函數的多播委托在現實世界中是否有用例?

說實話,很少見。 但是,您可以使用Delegate.GetInvocationList()拆分多播委托:

foreach (Func<string, string> 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<string, string> func in funcSum.GetInvocationList())
    {
        result = func(result);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM