首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Effective C# 原則 21:用委派表示回呼

     編輯:關於C語言

回呼的生活化範例

我:「兒子,到院子除草,我要看書。」
兒子:「爸,我已掃過院子了。」
兒子:「爸,草已放上除草機了。」
兒子:「爸,除草機啟動不了。」
我:「讓我來啟動。」
兒子:「爸,我做好了。」

這簡單互動展示回呼。我給兒子任務,他回報狀態打斷我。等待任務各部分完成時,我不阻塞自己進程。他可在重要狀態回報時定時打斷我,或尋求幫助。回呼用於非同步提供伺服器與客戶端間資訊回饋。可能在多執行緒,或簡單提供同步更新點。C# 用委派表示回呼。

委派提供型別安全的回呼定義

雖委派多用於事件,但不應是 C# 唯一使用此功能的地方。任何時候想在兩類別間通訊,又期望比介面更低耦合,委派是正確選擇。委派讓你在執行期決定回呼目標並通知使用者。委派包含某些方法參考,可為靜態或實例方法。使用委派,可在執行期決定與一或多個客戶物件互動。

多點傳送委派的兩個注意點

  • 非例外安全:委派鏈中拋出的任何例外會終止後續調用。
  • 回傳值永遠是委派上最後一個函數調用的回傳值。

回傳值問題與手動調用委派鏈

定義回呼函數檢測使用者中斷:

public delegate bool ContinueProcessing();
public void LengthyOperation(ContinueProcessing pred)
{
    foreach(ComplicatedClass cl in _container)
    {
        cl.DoLengthyOperation();
        if (false == pred()) return;
    }
}

單一委派可行,多點傳送委派有問題:

ContinueProcessing cp = new ContinueProcessing(CheckWithUser);
cp += new ContinueProcessing(CheckWithSystem);
c.LengthyOperation(cp);

委派調用回傳值實際是最後一個函數回傳值,其他被忽略(CheckWithUser() 斷言被忽略)。

解決方案:手動逐一調用委派鏈

public delegate bool ContinueProcessing();
public void LengthyOperation(ContinueProcessing pred)
{
    bool bContinue = true;
    foreach(ComplicatedClass cl in _container)
    {
        cl.DoLengthyOperation();
        foreach(ContinueProcessing pr in pred.GetInvocationList())
            bContinue &= pr();
        if (false == bContinue) return;
    }
}

此時定義程式語意:委派鏈上每個委派必須回傳 true 才繼續調用。

總結

委派為執行期回呼提供最佳方法,使用者簡單實作需求。可在執行期決定委派目標,支援多個使用者目標,使用者回呼在 .NET 中用委派實現。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved