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

白話解析 .NET 事件與委派:從買菜說起

     編輯:關於.NET

初學 C# 時,「委派」常被比喻為「C++ 函數指標」,對沒學過 C++ 的開發者而言無異天書。其實委派本質是一個「型別安全的函數參考」,它讓方法能像變數一樣被傳遞、儲存、呼叫。事件則是委派的受控封裝,實現「發布-訂閱」模式。本文用一個買菜的生活化例子,帶你輕鬆理解委派與事件的運作機制。

情境:老闆派采購員買菜

  • 需求:買白菜、馬鈴薯,最後算總價。
  • 白菜規則:價格 < 3 元按原價;≥ 3 元每公斤扣 0.3 公斤雜質再算價。
  • 馬鈴薯規則:老闆說「你自己決定」,采購員心裡盤算:價格 > 2.5 元才扣雜質。

白菜規則固定,直接寫死在方法裡;馬鈴薯規則不確定,必須在執行時才能決定,這就是委派的用武之地。

程式碼實作

1. 定義委派型別

/// 買馬鈴薯的委派:輸入單價與數量,回傳總價
public delegate double BuyPotatoDelegate(double price, double amount);

2. 買菜類別

public class VegetableBuyer
{
    double _cabbageTotal, _potatoTotal;

    // 白菜:固定規則
    public void BuyCabbage(double price, double amount)
    {
        _cabbageTotal = price < 3 ? price * amount : (price - 0.3) * amount;
    }

    // 馬鈴薯:宣告事件,型別為委派
    public event BuyPotatoDelegate PotatoPurchased;

    public void BuyPotato(double price, double amount)
    {
        // 呼叫事件(若有訂閱者),取得計算結果
        _potatoTotal = PotatoPurchased?.Invoke(price, amount) ?? 0;
    }

    public double GetTotal() => _cabbageTotal + _potatoTotal;
}

3. 使用端:訂閱事件並提供具體規則

protected void Page_Load(object sender, EventArgs e)
{
    var buyer = new VegetableBuyer();

    // 白菜直接買
    buyer.BuyCabbage(3.6, 8);

    // 馬鈴薯:先掛上自訂規則
    buyer.PotatoPurchased += PotatoRule;

    // 再買馬鈴薯
    buyer.BuyPotato(4.8, 9);

    Response.Write(buyer.GetTotal());
}

// 具體規則:價格 > 2.5 扣雜質
double PotatoRule(double price, double amount)
{
    return price > 2.5 ? (price - 0.3) * amount : price * amount;
}

核心觀念釐清

概念說明例子對應
委派型別定義方法簽章的「合約」BuyPotatoDelegate
委派實例指向具體方法的「變數」PotatoRule 方法
事件委派的「受控容器」,只能 += / -=,不能直接呼叫PotatoPurchased
發布者擁有事件的類別,決定何時觸發VegetableBuyer
訂閱者提供具體邏輯,註冊到事件Page_Load 中的 += PotatoRule

為什麼不用介面或多型?

委派比介面更輕量:無需定義完整類別、實作多個方法,單一行為即可封裝。事件更進一步限制外部只能訂閱/取消訂閱,不能任意呼叫或清空委派鏈結,保護封裝性。

總結

委派是「方法的參考型別」,事件是「委派的受控公開介面」。透過「買馬鈴薯規則由采購員現場決定」的例子,我們看到:固定邏輯寫死,變動邏輯委派,這正是委派/事件模式的核心價值——將「什麼時候做」與「怎麼做」分離,實現靈活的行為擴充。

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