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

C# 與 Java 深度比較(四):事件模型——Delegate/Event vs. 內部類/監聽器

     編輯:關於C語言

C# 事件模型原生支援

C# 以 delegate (類型安全函數指標) + event 關鍵字 直接語言層級支援事件,類似 MS VJ#。對比:

  • Delphi:函數指標 (Closure)
  • Java:匿名內部類實作介面 (Listener 模式)
  • VC++:Windows 訊息迴路

完整範例:比賽計分與裁判事件處理

// 1. 委派定義:事件簽名
public delegate void ScoreChangeEventHandler(int newScore, ref bool cancel);

// 2. 事件發布者
public class Game {
    public event ScoreChangeEventHandler ScoreChange;
    private int _score;
    public int Score {
        get => _score;
        set {
            if (_score != value) {
                bool cancel = false;
                ScoreChange?.Invoke(value, ref cancel); // 引發事件
                if (!cancel) _score = value;
            }
        }
    }
}

// 3. 事件訂閱者
public class Referee {
    public Referee(Game game) {
        game.ScoreChange += Game_ScoreChange; // 訂閱
    }
    private void Game_ScoreChange(int newScore, ref bool cancel) {
        if (newScore < 100) Console.WriteLine("Good Score");
        else { cancel = true; Console.WriteLine("No Score can be that high!"); }
    }
}

// 4. 測試
public class GameTest {
    public static void Main() {
        Game game = new Game();
        Referee referee = new Referee(game);
        game.Score = 70;  // Good Score
        game.Score = 110; // No Score can be that high! (分數不變)
    }
}

關鍵特性解析

  • 鬆耦合:Game 不知 Referee 存在,只負責引發事件
  • 多播:+=/-= 可為同一事件註冊/移除多個處理器
  • event 關鍵字限制:外部只能 +=/-=,不能直接 = 或 Invoke,保護封裝性

歷史趣聞

Delegate 由 Anders Hejlsberg 發明,首見於 MS VJ++。Sun 強烈反對,James Gosling 戲稱 Hejlsberg 為「函數指標先生」;回敬者稱 Gosling 為「全都是類先生」。

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