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

C# 自訂事件實作完整範例:委派宣告、訂閱與觸發

     編輯:關於C語言

事件發布者

public class ChatServer {
    // 1. 宣告委派型別
    public delegate void MessageHandler(string message);
    
    // 2. 宣告事件(基於委派)
    public event MessageHandler OnSendMessage;
    
    // 3. 觸發事件的方法
    public void SendMessage() {
        // 安全觸發:檢查是否有訂閱者
        OnSendMessage?.Invoke("開始發送訊息!");
        // 等同於:
        // if (OnSendMessage != null) OnSendMessage("開始發送訊息!");
    }
}

事件訂閱者

public class Form1 : Form {
    private void TestCustomEvent() {
        ChatServer server = new ChatServer();
        
        // 訂閱事件:使用 += 運算子
        server.OnSendMessage += Server_OnSendMessage;
        
        // 觸發
        server.SendMessage();
    }
    
    // 事件處理器:簽章必須符合委派
    private void Server_OnSendMessage(string msg) {
        Console.WriteLine($"[收到訊息] {msg}");
        // 或更新 UI:this.Invoke(...)
    }
    
    // 取消訂閱(可選,防止記憶體洩漏)
    private void Unsubscribe(ChatServer server) {
        server.OnSendMessage -= Server_OnSendMessage;
    }
}

進階模式

EventHandler 標準模式

public class ProgressReporter {
    // 使用標準 EventHandler<TEventArgs>
    public event EventHandler<ProgressEventArgs> ProgressChanged;
    
    protected virtual void OnProgressChanged(ProgressEventArgs e) {
        ProgressChanged?.Invoke(this, e);
    }
    
    public void DoWork() {
        for (int i = 0; i <= 100; i += 10) {
            OnProgressChanged(new ProgressEventArgs(i));
            Thread.Sleep(100);
        }
    }
}

public class ProgressEventArgs : EventArgs {
    public int Percent { get; }
    public ProgressEventArgs(int percent) { Percent = percent; }
}

自訂事件存取器

public class CustomEventAccess {
    private EventHandler<EventArgs> handlers;
    
    public event EventHandler<EventArgs> CustomEvent {
        add {
            lock (this) { handlers += value; }
            Console.WriteLine("訂閱者加入");
        }
        remove {
            lock (this) { handlers -= value; }
            Console.WriteLine("訂閱者移除");
        }
    }
    
    protected void Raise() {
        handlers?.Invoke(this, EventArgs.Empty);
    }
}

關鍵最佳實務

  1. null 條件運算子:Event?.Invoke(args) 取代 if (Event != null),執行緒安全
  2. 虛擬觸發方法:protected virtual void OnXxx() 允許衍生類別擴充
  3. EventArgs 衍生:傳遞豐富資料,遵循 .NET 命名慣例
  4. 取消訂閱:IDisposable 模式或明確 -=,防止記憶體洩漏
  5. 執行緒安全:事件欄位本身非執行緒安全,高併發場景考慮 lock 或 Interlocked
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved