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

C# 函式、委派與事件深度解析:從函式指標到觀察者模式的演進

     編輯:關於C語言

前言:一個經典的誤區引發的思考

作者分享一個教學案例:學生預期 object m_obj = m_isRight ? MyWrite("true") : MyWrite("false"); 會輸出 "false false",實際上這將函式呼叫結果(int)裝箱賦值給 object,而非函式本身。這反映出初學者直覺希望「函式也是一等物件,可直接賦值傳遞」——這正是委派存在的意義。

委派:型別安全的函式指標

核心三問與解答

  1. 如何區別不同函式? → 以簽章(回傳型別、參數型別/順序/數量)定義委派型別,如 delegate int MyDelegate(object obj);
  2. 如何區分「函式賦值」與「物件賦值」? → 宣告委派型別變數,實例化時傳入符合簽章的方法名:MyDelegate d = new MyDelegate(MyWrite);
  3. 如何透過委派物件呼叫原函式? → 直接以方法語法呼叫委派實例:d("參數"); 等同 MyWrite("參數");

完整委派範例

delegate int MyDelegate(object i_object);

static void Main()
{
    MyDelegate d = new MyDelegate(MyWrite);
    d("透過委派呼叫原函式");
}

static int MyWrite(object s) 
{ 
    Console.WriteLine(s); 
    return s.ToString().Length; 
}

事件:委派的封裝與多點廣播機制

事件解決「執行期動態增減處理函式」的需求,本質是對委派的受限封裝:

  • 宣告:event MyDelegate MyEvent;(外部不可直接賦值,只能 +=/-=)
  • 新增處理器:MyEvent += new MyDelegate(Handler); 或 MyEvent += Handler; (C# 2.0+)
  • 移除處理器:MyEvent -= Handler;(不存在不報錯)
  • 觸發:if (MyEvent != null) MyEvent(sender, args);(依序呼叫所有已註冊處理器)
  • 檢查訂閱數:MyEvent.GetInvocationList().Length

標準 .NET 事件模式範例

public delegate void MyEventHandler(object sender, object arg);

public class Publisher
{
    public event MyEventHandler OnError;
    public event MyEventHandler OnSomethingHappened;

    public void Run()
    {
        Random r = new Random();
        while (!stop)
        {
            int n = r.Next(100);
            if (n % 5 == 0) OnError?.Invoke(this, n);
            else OnSomethingHappened?.Invoke(this, n);
        }
    }
}

本質總結:三者關係圖譜

  1. 函式:程式基本單元,非物件
  2. 委派:將函式「盒裝」為物件的類別,每種簽章對應一個委派類別,實例綁定單一方法
  3. 事件:對委派的管理封裝,支援多點廣播、動態訂閱/取消,實現觀察者模式

理解此層級關係,即掌握 C# 事件驅動程式設計的核心。

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