亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

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

使用 .NET 對事件進行編程

2019-11-18 12:01:48
字體:
來源:轉載
供稿:網友

  您可能已經對事件進行編程若干年了,但是遷移到 .NET Framework 仍然需要您重新檢查事件的內部工作,因為 .NET Framework 中的事件位于委托的頂層。 對委托的了解越多,對事件進行編程時所具有的駕馭能力越強。 開始使用公共語言運行庫 (CLR) 的某個事件驅動框架(例如 Windows? Forms 或 asp.net)時,理解事件在較低的級別如何工作至關重要。 本月我的目標是使您理解事件在較低的級別如何工作。
  
  什么是事件?
  事件是一種形式化的軟件模式,在該模式中,通知源將對一個或多個處理程序方法進行回調。 因此,事件類似于接口和委托,因為它們提供了設計使用回調方法的應用程序的方法。 但是,事件極大地提高了工作效率,因為它們使用起來比接口或委托更輕易。 事件答應編譯器和 Visual Studio? .NET IDE 在幕后為您做大量的工作。
  
  涉及事件的設計基于事件源和一個或多個事件處理程序。 事件源可以是一個類也可以是一個對象。 事件處理程序是綁定到處理程序方法的委托對象。 圖 1 顯示了綁定到其處理程序方法的事件源的高級別視圖。
  
 使用 .NET 對事件進行編程(圖一)

  
圖 1 事件源和處理程序

  
  每個事件都是根據特定的委托類型定義的。 對于事件源定義的每個事件,有一個基于事件的基礎委托類型的私有字段。 該字段用于跟蹤多路廣播委托對象。 事件源還提供答應您注冊所需數量的事件處理程序的公用注冊方法。
  
  當您創建事件處理程序(委托對象)并在事件源中注冊它時,事件源只是將新的事件處理程序追加到列表的結尾。 然后,事件源可以使用私有字段在多路廣播委托上調用 Invoke,該多路廣播委托將依次執行所有注冊的事件處理程序。
  
  事件的真正的妙處在于對其進行設置的大量工作都已經為您做好了。 正如您很快就會看到的,無論任何時候您定義事件時,Visual Basic? .NET 編譯器都會通過自動添加私有委托字段和公用注冊方法幫助您工作。 您還將看到 Visual Studio .NET 可以通過代碼生成器提供更多的幫助,代碼生成器可以自動發出適用于您的處理程序方法的主干定義。
  
  對事件進行編程
  由于 .NET 中的事件建立在委托的頂層,因此它們的基礎的管道具體信息與較低版本的 Visual Basic 中所一直使用的截然不同。 但是,Visual Basic .NET 的語言設計者們在保持事件編程的語法與較低版本的 Visual Basic 一致方面做得很好。 在很多情況下,對事件進行編程涉及的語法與您習慣使用的熟悉的老語法相同。 例如,您將使用 Event、RaiseEvent 和 WithEvents 等要害字,而它們的行為方式與其在較低版本的 Visual Basic 中的行為方式幾乎完全相同。
  
  讓我們通過創建一個基于事件的簡單的回調設計開始。 首先,我需要通過使用 Event 要害字在類定義內定義一個事件。 必須根據特定的委托類型定義每個事件。 下面是定義自定義委托類型和用來定義事件的類的一個示例:
  
  Delegate Sub LargeWithdrawHandler(ByVal Amount As Decimal)
  
  Class BankAccount
   Public Event LargeWithdraw As LargeWithdrawHandler
   '*** other members omitted
  End Class
  
  在本示例中,LargeWithdraw 事件被定義為實例成員。 在本設計中,BankAccount 對象將充當事件源。 假如希望類而不是對象充當事件源,應該使用 Shared 要害字將事件定義為共享成員。
  
  對事件進行編程時,知道編譯器在幕后為您做了大量額外的工作這一點很重要。 例如,當您將我剛才向給您看過的 BankAccount 類的定義編譯到程序集時,您認為編譯器會做什么? 圖 2 顯示了在中間語言反匯編程序 ILDasm.exe 中檢查生成的類定義時,該定義是什么樣的。 該視圖毫無保留地向您顯示了 Visual Basic .NET 編譯器在幕后做了多少工作來幫助您。
  
使用 .NET 對事件進行編程(圖二)

  
圖 2 ILDasm 中的類定義

  
  當您定義事件時,編譯器在類定義內生成四個成員。 第一個成員是基于委托類型的私有字段。 該字段用于跟蹤對委托對象的引用。 編譯器通過采用事件本身的名稱并添加后綴“Event”生成該私有字段的名稱。 這意味著創建名為 LargeWithdraw 的事件將導致創建名為 LargeWithdrawEvent 的私有字段。
  
  編譯器還生成兩個方法,幫助注冊和注銷將成為事件處理程序的委托對象。 這兩個方法使用標準的命名規則進行命名。 用于注冊事件處理程序的方法使用事件的名稱,并帶有前綴“add_”。 用于注銷事件處理程序的方法使用事件的名稱,并帶有前綴“remove_”。 因此,為 LargeWithdraw 事件創建的兩個方法名為 add_LargeWithdraw 和 remove_LargeWithdraw。
  
  Visual Basic .NET 編譯器通過調用 Delegate 類的 Combine 方法為將委托對象作為參數接受并將其添加到處理程序列表中的 add_LargeWithdraw 生成一個實現。 編譯器通過在 Delegate 類中調用 Remove 方法為從列表中刪除一個處理程序方法的 remove_LargeWithdraw 生成一個實現。
  
  第四個也是最后一個添加到類定義中的成員是表示事件本身的成員。 在圖 2 中,您應該能夠找到名為 LargeWithdraw 的事件成員。 它是旁邊帶有一個倒三角的成員。 但是,您應該注重到,該事件并不象其它三個成員一樣真的是一個物理成員。 相反,它是一個僅包含元數據的成員。
  
  此僅包含元數據的事件成員很有價值,因為它可以向該類支持的編譯器和其他開發工具通知 .NET Framework 中事件注冊的標準模式。 該事件成員還包含注冊方法和注銷方法的名稱。 這使得 Visual Basic .NET 和 C# 等托管語言的編譯器可以在編譯時查找注冊方法的名稱。
  
  Visual Studio .NET 是查找此僅包含元數據的事件成員的開發工具的另一個很好的示例。 當 Visual Studio .NET 發現類定義包含事件時,它將自動生成處理程序方法的主干定義以及將它們作為事件處理程序進行注冊的代碼。
  
  在開始討論激發事件之前,我想提出一個有關用于定義事件的委托類型的限制。 用于定義事件的委托類型不能有返回值。 您必須使用 Sub 要害字而不是 Function 要害字定義委托類型,如下所示:
  
  '*** can be used for events
  Delegate Sub BaggageHandler()
  Delegate Sub MailHandler(ItemID As Integer)
  
  '*** cannot be used for events
  Delegate Function QuoteOfTheDayHandler(Funny As Boolean) As String
  
  對此限制有很充分的原因。 當涉及與若干處理程序方法綁定的多路廣播委托時,處理返回值相當困難。 在多路廣播委托上調用 Invoke 返回與調用列表中的最后一個處理程序方法相同的值。 但是,捕捉較早在列表中出現的處理程序方法的返回值并不那么簡單。 不需要捕捉多個返回值只會使事件更輕易使用。
  
  激發事件
  現在,讓我們修改 BankAccount 類使其在提款數量超出 $5000 閾值時能夠激發一個事件。 激發 LargeWithdraw 事件的最簡單的方法是在一個方法、屬性或構造函數的實現中使用 RaiseEvent 要害字。 您可能會覺得該語法很熟悉,因為它類似于您在較低版本的 Visual Basic 中使用的語法。 下面是從 Withdraw 方法激發 LargeWithdraw 事件的一個示例:
  
  Class BankAccount
   Public Event LargeWithdraw As LargeWithdrawHandler
   Sub Withdraw(ByVal Amount As Decimal)
  '*** send notifications if required
  If (Amount > 5000) Then
   RaiseEvent LargeWithdraw(Amount)
  End If
  '*** perform withdrawal
   End Sub
  End Class
  
  雖然語法與較低版本的 Visual Basic 相同,但是激發事件時所發生的事情則與現在截然不同。 使用 RaiseEvent 要害字激發事件時,Visual Basic .NET 編譯器生成執行每個事件處理程序所需的代碼。 例如,當您編譯以下代碼時您認為會出現什么情況?
  
  RaiseEvent LargeWithdraw(Amount)
  
  Visual Basic .NET 編譯器將此表達式擴展為在保留多路廣播委托對象的私有字段上調用 Invoke 的代碼。 換句話說,使用 RaiseEvent 要害字與在以下 snippet 中編寫代碼具有完全相同的效果:
  
  If (Not LargeWithdrawEvent Is Nothing) Then
   LargeWithdrawEvent.Invoke(Amount)
  End If
  
  注重,Visual Basic .NET 編譯器生成的代碼執行檢查以確保 LargeWithdrawEvent 字段包含對某個對象的有效引用。 這是因為 LargeWithdrawEvent 字段的值在第一個處理程序方法注冊之前一直為 Nothing。 因此,除非當前至少有一個處理程序方法已注冊,否則生成的代碼并不嘗試調用 Invoke。
  
  您應該能夠對激發事件進行觀察。 使用 RaiseEvent 要害字或者根據編譯器自動生成的 LargeWithdrawEvent 私有字段直接進行編程通常并沒有什么分別。 兩種方法都生成相同的代碼:
  
  '*** this code
  RaiseEvent LargeWithdraw(Amount)
  
  '*** is the same as this code
  If (Not LargeWithdrawEvent Is Nothing) Then
   LargeWithdrawEvent.Invoke(Amount)
  End If
  
  在很多情況下,您可能喜歡使用 RaiseEvent 要害字語法,因為它需要的鍵入較少,生成的代碼較簡潔。 但是,在某些情況下,當您需要較多控制時,根據 LargeWithdrawEvent 私有字段進行明確編程可能會有意義。 讓我們看一個這種情況的示例。
  
  想象以下情況:BankAccount 對象有三個事件處理程

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲人成电影网站色…| 国产精品伦子伦免费视频| 国产精品黄视频| 国产精品极品尤物在线观看| 美女撒尿一区二区三区| 国产91精品视频在线观看| www亚洲精品| 日韩视频免费观看| 97色在线观看免费视频| 在线视频免费一区二区| 欧美激情精品久久久久久蜜臀| 亚洲人成在线观| 国产精品国语对白| 欧美日韩免费区域视频在线观看| 成人国产精品一区二区| 国产专区欧美专区| 亚洲精品黄网在线观看| 日韩在线视频网| 91美女片黄在线观| 色噜噜久久综合伊人一本| 欧美亚洲激情视频| 国产成人一区二区三区电影| 亚洲国产女人aaa毛片在线| 精品高清美女精品国产区| 欧美精品日韩www.p站| 日本午夜在线亚洲.国产| 亚洲天堂日韩电影| 欧美洲成人男女午夜视频| 国产精品视频一区二区高潮| 欧美日韩亚洲精品内裤| 最近2019年手机中文字幕| 亚洲男人av电影| 色偷偷亚洲男人天堂| 亚洲在线免费看| 国产suv精品一区二区三区88区| 久久影院中文字幕| 午夜精品三级视频福利| 亚洲人成在线免费观看| 国产一区二区美女视频| 欧美精品精品精品精品免费| 欧美极品少妇xxxxⅹ免费视频| 上原亚衣av一区二区三区| 亚洲人成啪啪网站| 国产视频精品自拍| 亚洲福利视频免费观看| 海角国产乱辈乱精品视频| 亚洲精品视频久久| 成人动漫网站在线观看| 夜夜狂射影院欧美极品| 国产精品女人网站| 成人中文字幕+乱码+中文字幕| 日韩一区二区在线视频| 91精品国产综合久久久久久蜜臀| 亚洲人成在线观| 日韩欧美成人区| xvideos国产精品| 中文字幕一区二区精品| 亚洲自拍高清视频网站| 日韩精品免费视频| 97精品视频在线播放| 在线成人一区二区| 国产精品视频区1| 国产精品一区二区三区免费视频| 日韩欧美在线视频观看| 成人淫片在线看| 亚洲视频在线免费观看| 亚洲精品视频在线观看视频| 国产成人午夜视频网址| 国产亚洲欧美日韩一区二区| 亚洲欧美国产日韩天堂区| 国产v综合ⅴ日韩v欧美大片| 亚洲国产成人91精品| 国产日韩欧美日韩大片| 亚洲自拍在线观看| 亚洲成人黄色网| 国产精品三级美女白浆呻吟| 91高潮精品免费porn| 国产精品永久免费| 欧美日韩黄色大片| 亚洲精品免费在线视频| 欧美又大粗又爽又黄大片视频| 久久久久久中文| 日韩av综合网| 久久亚洲国产精品| 精品国产乱码久久久久酒店| 国产精品999999| 亚洲精品成a人在线观看| 欧美日韩国产第一页| 精品中文字幕在线2019| 国模精品一区二区三区色天香| 日本精品性网站在线观看| xxav国产精品美女主播| 精品国产鲁一鲁一区二区张丽| 亚洲男人天天操| 欧美高跟鞋交xxxxhd| 成人久久一区二区| 精品久久香蕉国产线看观看亚洲| 色婷婷**av毛片一区| 欧美成人精品三级在线观看| 欧美性极品xxxx做受| 亚洲国产精品久久精品怡红院| 国产成人avxxxxx在线看| 亚洲精品97久久| 人人澡人人澡人人看欧美| 成人亚洲欧美一区二区三区| 黑人与娇小精品av专区| 国产精品视频在线观看| 97超碰国产精品女人人人爽| 国产成人精品免高潮在线观看| 欧美亚洲伦理www| 精品福利视频导航| 国产亚洲美女精品久久久| 欧洲日韩成人av| 青草青草久热精品视频在线观看| 国产v综合v亚洲欧美久久| 亚洲欧美色图片| 夜夜嗨av色综合久久久综合网| 欧美丰满少妇xxxxx做受| 国产精品人人做人人爽| 亚洲精品一区中文字幕乱码| 欧美激情一区二区三区在线视频观看| 国产精品欧美日韩| 国产亚洲xxx| 国产主播喷水一区二区| 国产精品久久久久91| 精品人伦一区二区三区蜜桃免费| 欧美大片大片在线播放| 欧美激情中文字幕在线| 亚洲伊人久久大香线蕉av| 国产精品色婷婷视频| 久99久在线视频| 精品成人av一区| 91久久嫩草影院一区二区| 中文字幕最新精品| 亚洲欧美国产va在线影院| 国模叶桐国产精品一区| 国产精品情侣自拍| 国产精品美女免费| 精品久久中文字幕久久av| 国产成人精品视| 久热爱精品视频线路一| 日韩欧美精品网站| 久久6免费高清热精品| 91香蕉嫩草影院入口| 久久99久久99精品免观看粉嫩| 欧美高清理论片| 久久亚洲国产精品成人av秋霞| 91香蕉电影院| 亚洲激情视频在线观看| 久久免费国产视频| 国产激情久久久| 日韩福利视频在线观看| 亚洲精品av在线| 亚洲天堂成人在线视频| 麻豆精品精华液| 欧美精品久久久久久久| 精品免费在线视频| 久久久久久亚洲| 在线视频日本亚洲性| 中文字幕日韩欧美| 国产精品99久久久久久人| 亚洲天堂一区二区三区| 日韩av一区二区在线观看| 国产精品一区二区三|