C 中委託 delegate 和多播委託的理解

2021-08-29 10:15:49 字數 3144 閱讀 9715

委託是定址方法的.net版本。

在c#高階程式設計(第七版)中這是對委託的第一句描述。

什麼是定址方法?

簡單理解為我們通過委託傳遞乙個方法給另乙個方法。

什麼時候需要傳遞方法?

在微軟的官方文件和c#高階程式設計(第七版)這本書都提到乙個例子-----在物件的排序演算法中,需要對物件進行比較,而不同物件比較的方法不同,所以比較兩個物件的方法的引用可以作為引數傳遞到排序演算法中,這個時候就需要傳遞方法。

通過什麼傳遞方法?

在理解委託的時候經常將其與c++中的函式指標做比較,函式指標只是乙個指向記憶體位置的指標,它不是型別安全的,我們無法判斷這個指標實際指向什麼,引數和返回型別更加無從知曉。但我們可以通過該函式指標獲得該方法也可以理解為通過傳遞位址來傳遞該方法

函式指標是面向過程的,而c#是物件導向程式設計,幾乎沒有方法是孤立存在的,而是在呼叫方法之前需要與類的例項相關聯。

所以.net框架不允許使用函式指標這種直接的方法,因為這這很不物件導向!

那如何才符合物件導向的核心價值觀?——————委託

在c#中要傳遞方法,就必須把方法的細節封裝在一種新型別的物件中,即委託。委託只是一種特殊型別的物件,其特殊之處在於,我們定義的所有物件都包含資料,而委託包含的只是乙個或多個方法的位址。總結

委託是一種引用型別,表示對具有特定引數列表和返回型別的方法的引用。 在例項化委託時,你可以將其實例與任何具有相容簽名和返回型別的方法相關聯。 你可以通過委託例項呼叫方法。

委託用於將方法作為引數傳遞給其他方法。

這符合.net規範,對比函式指標,委託是物件導向的、型別安全的和可靠的,但也損失了靈活性!

宣告乙個委託:

public delegate int operation(int num1, int num2);
該委託表示的方法有倆個int型別的引數,返回值也為int型別。

要注意的是其語法類似於方法的定義,但沒有方法體,關鍵字為delegate

定義委託相當於定義乙個新類(其實還真是定義乙個類),所有定義的位置可以是在定義類的任何相同的地方,可以在類的內部或者外部定義。

可以例項該委託的方法(即方法的引數和返回值和委託一致):

也可以說是可以被該委託封裝的方法

// create  methods for a delegate.

public int add(int num1,int num2)

public int reduce(int num1, int num2)

例項委託:

在官方文件和高階程式設計書中可以看到兩種例項方法:

operation someoperation = new operation(reduce);//法一:通過在委託的建構函式中新增委託引用的方法

//operation someoperation = add;//法二:直接讓委託物件等於引用的方法

呼叫委託:

someoperation (num1,num2);
注意:

因為委託的例項為乙個物件所有,可以作為乙個方法的引數:

public int nummethod(int num1, int num2, operation callback)

並且我們可以將委託的例項傳入該方法,也可以直接將方法傳入

operation someoperation = new operation(reduce);

int result = nummethod(2, 1, someoperation);//法一:傳入委託例項

//int result = nummethod(2, 1, reduce);//法二:直接傳入方法

委託可以呼叫多個方法。 這被稱為多播。 若要向委託的方法列表(呼叫列表)新增其他方法,只需使用加法運算子或加法賦值運算子(「+」或「+=」)新增兩個委託,也可以通過(「-」或「-=」)去除委託。 例如:

methodclass obj = new methodclass();

del d1 = obj.method1;

del d2 = obj.method2;

del d3 = obj.method3;

//新增多個委託

del allmethodsdelegate = d1 + d2;

allmethodsdelegate += d3;

------------------------------------------

//去除委託的方法

allmethodsdelegate -= d1;

// copy allmethodsdelegate while removing d2

del onemethoddelegate = allmethodsdelegate - d2;

注意3個方法都是該委託可以封裝的方法,且多播委託封裝的方法返回值必須都為void,不然只能得到呼叫最後乙個方法的結果。

最後:

多播委託廣泛用於事件處理中。 事件源物件將事件通知傳送到已註冊接收該事件的接收方物件。 若要註冊乙個事件,接收方需要建立用於處理該事件的方法,然後為該方法建立委託並將委託傳遞到事件源。 事件發生時,源呼叫委託。 然後,委託將對接收方呼叫事件處理方法,從而提供事件資料。 給定事件的委託型別由事件源確定。

action和func泛型委託,委託,泛型,匿名函式,lambda表示式的綜合使用

事件(event)和委託(delegate)的綜合運用例項(winform控制項事件執行流程和原理),和eventhandler委託

c 委託 與多播委託delegate

委託又叫匿名函式,首先我們來說為什麼要使用委託 委託到底是什麼 舉乙個例子 我想求煉表裡少於10的數的和,getsum static int getsum listlist return sum 我又想求煉表裡所有奇數的和,那麼是否是又要寫乙個函式getsum2 來求呢 static int get...

C 多播委託

昨天第一次學到了多播委託,記錄一下最簡單的用法。顧名思義,多播委託就像廣播一樣,由乙個委託例項引用多個方法。通過 和 運算子實現對引用方法的增加和減少。1 static void main string args 211 public static void test1 1215 public st...

C 多播委託

乙個委託呼叫多個方法 例如 action a test1 a test2 增加乙個新方法,按順序執行,只能得到最後乙個方法的值 a test2 減去乙個方法 當a為空時會報錯,如果乙個方法出錯,其餘不會呼叫 取得乙個多播委託的所有方法 getinvocationlist 返回值為delegate 陣...