事件宣告完整語法
[attributes] [event-modifiers] event 委派型別 事件名稱
[ { add { ... } remove { ... } } ];
事件修飾詞對照表
| 修飾詞 | 說明 | 互斥限制 |
| new | 遮蔽基類別同名事件 | 無 |
| public/protected/internal/private | 存取層級 | 單一 |
| static | 靜態事件,屬於類別 | 不可與 virtual/override/abstract 共存 |
| virtual | 允許衍生類別 override | 不可與 static/override/abstract 共存 |
| override | 覆寫基類別 virtual 事件 | 不可與 static/virtual/abstract 共存 |
| sealed | 禁止進一步 override | 需配合 override |
| abstract | 強制衍生類別實作 | 不可與 static/virtual/override 共存;不可提供存取器實作 |
抽象事件特殊規則
- 宣告時不可提供存取器區塊,否則編譯錯誤(CS0547)。
- 衍生類別必須使用
override 實作完整存取器或依賴編譯器自動產生。
- 抽象類別可包含抽象事件,介面也可宣告事件(隱含 abstract)。
委派型別需求
- 事件型別必須是委派型別(
delegate 關鍵字宣告)。
- 慣用
EventHandler 或 EventHandler<TEventArgs>。
- 自訂委派需符合
void DelegateName(object sender, TEventArgs e) 簽章慣例。
一次宣告多個事件
public event EventHandler Click, DoubleClick, MouseDown;
// 等同於分別宣告三個事件,共用同一委派型別
編譯器自動產生的預設實作
若省略存取器,編譯器會產生:
- 私有委派欄位
_eventName。
- 同步化的
add/remove 存取器(使用 lock(this) 或 Interlocked.CompareExchange)。
常見錯誤代碼對照
| 錯誤碼 | 原因 | 修正 |
| CS0067 | 事件從未被引發 | 加入引發邏輯或標記 #pragma warning disable 67 |
| CS0547 | 抽象事件提供存取器實作 | 移除存取器區塊 |
| CS0111 | 重複宣告同名事件 | 檢查基類別是否已宣告,使用 new/override |