委派是 C# 的核心特性,可視為「類型安全、物件導向的函式指標」。微軟在 MSVJ++ 6.0 中首次引入,旨在取代 C++ 指標,故譯為「指代」或「委派」。Sun 強烈反對,引發雙方激烈辯論。
C# 以 delegate 與 event 關鍵字直接支援事件模型,區別於 Delphi 的閉包、Java 的介面適配、VC++ 的訊息迴圈。
// 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 { return 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!
}
}
event 關鍵字限制委派僅能在類別內部觸發,對外僅暴露 +=/-= 訂閱/取消訂閱操作。Game 類別完全不感知 Referee 存在,實現鬆耦合。Anders Hejlsberg(委派發明者)被 James Gosling 戲稱「函式指標先生」;而 Java 大量使用介面,Gosling 反被戲稱為「全都是介面先生」。