C委託與事件

2021-04-04 09:18:10 字數 3412 閱讀 9502

我們拋棄各種c#參考書中桀驁難懂的事件與委託概念,設想乙個情景來理解事件與委託的使用:有一家it公司,董事長不希望自己的雇員在上班時間玩遊戲,但又不可能每時每刻都盯著每個雇員,因此,他希望使用一種新的方式實現監視雇員的效果:如果有雇員違反規定,某個裝置或專門的監查人員將自動發出乙個訊息通知他,董事長只需要在事情發生時進行處理。

因此,這個用例實際上是兩種型別——董事長類與雇員類——之間的互動,下面的**將給讀者展示如何使用委託與事件機制實現這種互動:

首先,我們需要在董事長類與雇員類之間定義乙個委託型別,用於傳遞兩者之間的事件,這個型別就是乙個監視裝置或專門負責打小報告的監查人員:

public delegate void delegateclasshandle();

定義乙個委託的過程類似方法的定義,但它沒有方法體。定義委託一定要新增關鍵字delegate。由於定義委託實際上相當乙個類,因此可以在定義類的任何地方定義委託。

另外,根據委託的可見性,也可以新增一般的訪問修飾符,如public、private和protected。

委託的返回值型別為void,這並非表示委託型別本身帶有返回值,該返回值型別是指委託的目標函式型別,即它委託的乙個事件處理函式返回值是void型別。

新建乙個雇員類employee,其**如下:

public class employee }}

,它的定義方式也很特殊,首先必須使用關鍵字event,表示playgame是乙個事件,同時還必須宣告該事件的委託型別為delegateclasshandle,即將來由該型別的委託物件負責通知事件。

如果有雇員開始玩遊戲,它將執行games方法,而只要該方法一被呼叫,就會觸發乙個事件playgame,然後董事長就會收到這個事件的訊息——有人在玩遊戲了。

董事長類**如下,他有乙個方法notify用於接收訊息:

public class admin

}employee的playgame事件如何與admin的notify方法關聯起來呢?只需通過事件繫結即可實現,具體過程如下列**:

employee employee = new employee();

admin admin = new admin();

employee.playgame += new delegateclasshandle(admin.notify);

請大家注意事件繫結的**:

employee.playgame += new delegateclasshandle(admin.notify);

通過delegateclasshandle將兩個類的互動進行了繫結,當方法呼叫後,觸發playgame事件,而該事件將被委託給admin的notify方法處理,通知董事長有雇員在上班時間玩遊戲。

但董事長並不滿足這種簡單的通知,他還想知道究竟是誰在上班時間違反規定。顯然,現在委託物件必須傳遞必要的引數才行,這個要求也可以很容易地辦到。事件的引數可以設定為任何型別的資料,在.

net框架中,還提供了事件引數基類eventargs專門用於傳遞事件資料。

從該eventargs類派生乙個自定義的事件引數類customeeventargs,這個型別將攜帶雇員姓名和年齡資訊:

public class customeevetnargs : eventargs

public string name

set} public int age

set }}

修改委託型別delegateclasshandle的定義,讓其攜帶必要的引數:

public delegate void delegateclasshandle(object sender, customeevetnargs e);

雇員類的**修改後如下:

public class employee

set} private int _age;

public int age

set} public event delegateclasshandle playgame;

public void games() }

}在games方法中,首先新建乙個customeeventargs物件,然後設定了必要的屬性name和age。

董事長的通知方法也必須相應地進行修改:

public class admin

}將兩個型別物件進行關聯的**也需要進行相應的修改:

employee employee = new employee();

= "mike";

employee.age = 25;

admin admin = new admin();

employee.playgame += new delegateclasshandle(admin.notify);

修改後的**執行的結果是,當mike呼叫games方法玩遊戲時,會自動觸發playgame事件,而該事件攜帶相關資訊通知admin,後者的notify方法將接收到資料並輸出「mike is 25」,告訴董事長是mike,25歲,正在上班時間玩遊戲。

委託是可以多路廣播(mulitcast)的,即乙個事件可以委託給多個物件接收並處理。在上面的用例中,如果有另一位經理與董事長具有同樣的癖好,也可以讓委託物件將雇員的playgame事件通知他。

首先定義經理類:

public class manager

}經理manager型別的notify方法與admin一致,他也接受到相應的資訊。

委託的多路廣播繫結的方法仍然是使用+=運算子,其方法如下面的**所示:

employee employee = new employee();

= "mike";

employee.age = 25;

admin admin = new admin();

manager manager = new manager();

employee.playgame += new delegateclasshandle(admin.notify);

employee.playgame += new delegateclasshandle(manager.notify);

執行該方法,讀者將看到admin和manager的notify方法都會被事件通知並呼叫執行。通過這樣的方法,董事長和經理都會知道mike在玩遊戲了。

如果董事長不希望經理也收到這個通知,該如何解除playgame對manager的事件繫結呢?同樣非常簡單,在方法被呼叫前執行下列語句即可:

employee.playgame -= new delegateclasshandle(manager.notify);

最後需要提醒讀者注意的,employee類中的games方法在觸發事件playgame之前需要判斷該事件是否為null。當employee物件的games方法觸發事件playgame後,必須有乙個目標函式來處理這個事件,而該語句正是判斷該目標函式是否存在。如果將這個判斷去掉,且對事件不進行任何繫結而直接呼叫games方法,程式將在事件playgame處彈出乙個nullreferenceexception的異常。

c委託與事件詳解

c 委託與事件詳解.txt花前月下,不如花錢 日 下。葉子的離開,是因為風的追求還是樹的不挽留?乾掉熊貓,我就是國寶!別和我談理想,戒了!委託和事件在 framework中的應用非常廣泛,然而,較好地理解委託和事件對很多接觸c 時間不長的人來說並不容易。它們就像是一道檻兒,過了這個檻的人,覺得真是太...

C委託與事件的例子

第乙個例子 public delegate void eateventhandler object sender,eateventargs e 這個的定義也可以不要這樣.可以直接就定義乙個引數 public delegate void eateventhandler string e 但然用的時候的...

C委託事件

有事件,就會有對事件進行處理的方法,而事件和處理方法之間是怎麼聯絡起來的呢?委託就是他們中間的橋梁,事件發生時,委託會知道,然後將事件傳遞給處理方法,處理方法進行相應處理。事件的型別一定是委託,委託為引發事件的類擔當事件傳送器的角色 比如在winform中最常見的是按鈕的click事件,它是這樣委託...