国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

對.Net事件委托的深入分析

2019-11-17 04:58:36
字體:
來源:轉載
供稿:網友

  “委托”機制的“委托”到底是什么意思呢,《高級漢語大詞典》中是如下解釋的:托付給別的人或機構辦理。要說生活中的意思其實大家都能理解,無非是“當某人(機構)需要完成一件自己不能或不應該完成的事情的時候,此人(機構)物色一個合適的且有能力完成此事的人選,然后提供必要的信息,將此事委托給物色到的人(機構)來完成?!?

  軟件的對象方法其實是對現實世界的模擬,你可能會想現實世界里的委托哪有這么多呢?這么重要呢?其實你也許沒有注重到老板把厚厚的一摞資料摔在你的案頭讓你無論如何在×月×日前交活,這不就是一種委托嗎?當然也許沒有委托書(和委任狀),但它就是委托。這樣看委托是不是就非常重要了,它甚至是構成現實社會的基礎機制之一。

  從這個意義上理解委托機制的重要性我想應該是足夠了。委托機制是促使事件發送與事件接受的一種對接策略,對象對四周信號的反應或在一定環境中所具備的對其它對象的通知行為的響應則被描述成所謂的“事件”,這可以類比人對四周世界反饋產生信號的能力。

  委托就是一種定向信號流:指定產生、接受信號者并產生信號反饋的技術。

  我可愛的小女兒才剛剛學會說話就在飯桌上支使她可憐的“老”爸:爸爸,把我的小勺子拿來。我接到“信號”立即屁顛屁顛地跑到廚房拿到勺子送到女兒的小手上,一個“委托”完成的非常漂亮,而女兒則無須知道我在什么地方、如何拿到勺子,她只管接受到我給她專門買的小勺子就行,否則,她就要仰著小臉“哇哇”大哭了。

  先說說事件委托的基礎。

  為了說明問題我設計了一個窗體還有幾個按鈕的示例DelegateDemo1項目,以便可以直觀感受委托的基本用法。

  至于委托在.Net中的實現,編譯器會自動生成一個完整的類定義:一個構造器,Invoke,BeginInvoke,以及EndInvoke。

  C#2003中隱式使用Invoke(其顯式調用會報錯)會讓我們誤解有一個以委托名稱為名稱的函數,其實沒有,它只是隱式使用Invoke方法。而VB.net包括最新的VB.net2005均可以采取兩種方法(顯式或隱式)使用Invoke方法。我比較喜歡顯式使用它,因為這樣比較貼近事物的本質。

  回到示例,代碼如下(使用VB.net2003并出去VS自動生成的代碼):

1 Public Class Form1Class Form1
2
3 Inherits System.Windows.Forms.Form
4
5 PRivate Sub Button1_Click()Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click, Button4.Click
6
7 Select Case CType(sender, Button).Name
8
9 Case "Button1"
10
11 MessageBox.Show("你點擊了Button1!", "委托提示", MessageBoxButtons.OK)
12
13 Case "Button2"
14
15 MessageBox.Show("你點擊了Button2!", "委托提示", MessageBoxButtons.OK)
16
17 Case "Button3"
18
19 MessageBox.Show("你點擊了Button3!", "委托提示", MessageBoxButtons.OK)
20
21 Case "Button4"
22
23 MessageBox.Show("你點擊了Button4!", "委托提示", MessageBoxButtons.OK)
24
25 End Select
26
27 End Sub
28
29 Private Sub Button2_Click()Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
30
31 MessageBox.Show("Button2的Click事件,注重執行順序!", "委托提示", MessageBoxButtons.OK)
32
33 End Sub
34
35 Private Sub Button3_Click()Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
36
37 Dim Demohandler1 As DemoHandler
38
39 Demohandler1 = AddressOf Button1_Click
40
41 Demohandler1.Invoke(sender, e)
42
43 Dim Demohandler2 As DemoHandler
44
45 Demohandler2 = AddressOf Button2_Click
46
47 Demohandler2(sender, e)
48
49
50
51 End Sub
52
53 Private Sub Button4_Click()Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
54
55 End Sub
56
57 Private Sub Button5_Click()Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
58
59 End Sub
60
61 Private Sub Form1_DoubleClick()Sub Form1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.DoubleClick, Button5.Click
62
63 If TypeOf sender Is Button Then
64
65 If MessageBox.Show("你確定退出嗎?", "退出提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) = DialogResult.Yes Then
66
67 Me.Close()
68
69 Else : Exit Sub
70
71 End If
72
73 Else : Me.Close()
74
75 End If
76
77 End Sub
78
79End Class
80
  Button1按鈕的click事件的代碼只需看看Handles子句,不僅有Button1.Click還有Button2.Click, Button4.Click,MSDN上說:在過程聲明結尾處使用Handles要害字將使其處理由使用 WithEvents 要害字聲明的對象變量所引發的事件。也可以在派生類中使用Handles要害字處理基類的事件。其實Handles子句答應任何與事件的參數簽名相符的過程來響應這個事件。這實際上就是委托。在編譯時間,.NET Framework用你的事件名稱創建一個委托類,只是在結尾添加“EventHandler”字樣。換言之,事件是使用委托來實現的,委托是面向對象函數指針的一種形式,它答應通過對函數進行引用的方法來間接地調用該函數。

  用Ildasm.exe反匯編DelegateDemo1.exe,請看下圖:


對.Net事件委托的深入分析(圖一)

  雙擊set_Button1方法或其他set_...方法,你都可以看到有System.EventHandler類出現。.NET Framework 中的事件模型基于具有事件委托,System.EventHandler將事件與事件處理程序連接。

  Button1的Click事件過程中的Select Case…End Select功能是根據點擊按鈕的名稱來選擇事件處理程序。

  Button3的Click事件過程要好好看看的。如下表:

語 句釋 義Dim Demohandler1 As DemoHandler定義一個DemoHandler委托的實例,DemoHandler可以換成 EventHandlerDemohandler1 = AddressOf Button1_ClickAddressOf可以認為就是將該委托和Button1_Click綁定Demohandler1.Invoke(sender, e)顯式使用委托的Invoke方法調用事件處理程序Dim Demohandler2 As DemoHandler定義一個DemoHandler委托的實例,DemoHandler2Demohandler2 = AddressOf Button2_Click同上AddressOfDemohandler2(sender, e) 隱式使用委托的Invoke方法調用事件處理程序
  Button4按鈕的click事件過程為空,因為在Button1_Click的Handles子句中已經注冊,且由于它們的事件簽名完全一致,故調用Button1_Click事件處理過程。

  Button5按鈕的click事件過程也為空,不要著急,下面的Form1_DoubleClick事件處理過程的Handles子句中注冊了Button5,所以Button5的click事件的事件處理程序調用Form1的DoubleClick事件的事件處理程序。

  在Form1的DoubleClick事件處理過程使用對控件類型的判定來選擇處理方式。

  我不說你也看出來了,這樣寫代碼,就可以將一些本來需要重復多次的代碼省去,符合重構的思想,使得代碼盡量簡約而由不失可讀性。

  現實生活中委托別人辦的事能不能辦好取決于以下兩個方面:

  1、是否委托給了合適的人;

  2、是否把解決委托事件所需的正確和必要的信息傳遞給了它。

  比如女兒委托我拿勺子,這個委托是相當成功的,因為她委托給了我(人選合適)且明確要她的小勺(正確和必要的信息傳遞)。

  對應到.Net框架中的委托,一是要有委托對象,二是要簽名相符。

  項目編譯運行后,點擊Button3按鈕有如下圖顯示:

對.Net事件委托的深入分析(圖二)

  點擊“確定”后有:

對.Net事件委托的深入分析(圖三)

  點擊“退出”Button5按鈕有:

對.Net事件委托的深入分析(圖四)

(注:以上內容描述多有個人理解的表述,歡迎大家批評指正,如有時間我會繼續寫如多路廣播委托及使用委托的需求方面的內容)

  備注:

  引用:(下面這段是我看到過對委托概念及特點最為言簡意賅的描述之一)

  委托是用來處理其他語言(如 C++、Pascal 和 Modula)需用函數指針來處理的情況的。不過與 C++ 函數指針不同,委托是完全面對對象的;另外,C++ 指針僅指向成員函數,而委托同時封裝了對象實例和方法。 委托聲明定義一個從 System.Delegate 類派生的類。委托實例封裝一個調用列表,該列表列出一個或多個方法,其中每個方法均作為一個可調用實體來引用。對于實例方法,可調用實體由該方法和一個相關聯的實例組成。對于靜態方法,可調用實體僅由一個方法組成。用一個適當的參數集來調用一個委托實例,就是用此給定的參數集來調用該委托實例的每個可調用實體。

  委托實例的一個有趣且有用的屬性是:它不知道也不關心它所封裝的方法所屬的類;它所關心的僅限于這些方法必須與委托的類型兼容(第 15.1 節)。這使委托非常適合于“匿名”調用。——《C#語言規范》Scott Wiltamuth 和 Anders Hejlsberg

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 广宗县| 遵化市| 浙江省| 土默特右旗| 获嘉县| 民乐县| 嵊泗县| 通州市| 长寿区| 达尔| 西乌珠穆沁旗| 康乐县| 漠河县| 稷山县| 改则县| 泾阳县| 滨州市| 湖口县| 湟中县| 辽宁省| 怀宁县| 博爱县| 冷水江市| 和硕县| 朝阳县| 姜堰市| 鲁山县| 浮梁县| 孝感市| 茶陵县| 张家口市| 云阳县| 兴化市| 威信县| 赤城县| 赤水市| 儋州市| 绿春县| 广宗县| 久治县| 红安县|