2013-04-29 38 views
1

我在問具體的VB.NET,但我想象一般原則在其他語言中是一樣的。我認爲一個事件是.NET中的一流概念,但從reflection看來,它只是一個特定的方法,它在事件引發時被調用。如何實施事件

  1. 如何AddHandlerRemoveHandler修改方法動態(據我所知,事件pre-日期DynamicMethod S'
  2. 如何RaiseEvent調用的方法?
  3. 爲什麼AddHandlerRemoveHandler,並RaiseEvent實現陳述而不是方法

回答

2

不,一個事件只是兩個或三個方法的組合(「raise」部分是可選的),方法與屬性是一個或兩個方法的組合相同。

AddHandlerRemoveHandler根本不修改方法。他們只是調用事件的「添加」和「刪除」部分,這些部分是實現部分的一部分。

通常情況下,事件通過對具有適當委託類型的字段的引用來實現,其中Delegate.CombineDelegate.Remove用於執行適當的操作。 (字段值將被更改 - 請記住,委託類型是不可變的。)引發事件僅包含調用委託。

至於爲什麼AddHandler等是單獨的語句類型 - 如果它們是方法,參數是什麼?有些事情必須提及「事件」。基本上,AddHandler語句對應於適當的事件「add」方法,就像屬性獲取對應於適當的屬性「get」方法一樣。你可以用反射做到這一點,通過EventInfo.AddHandler

請參閱我的article on delegates and events瞭解更多詳情,這可能有所幫助 - 它來自C#背景,但其原理顯然是相同的。

+0

這是否意味着'RaiseEvent SomeEvent'和'SomeEvent()'具有相同的影響(其中'SomeEvent'被聲明爲'Public Event SomeEvent As Action')。在VS2010中使用'SomeEvent()'語法給我一個編譯錯誤,我必須使用'RaiseEvent'語法。 – 2013-04-29 14:52:22

+0

@ just.another.programmer:嗯,我相信如果你能夠得到這個值,他們會有同樣的效果,但是這是VB方面的一個細節,我不太熟悉。 – 2013-04-29 14:54:54

1

事件只是一個代表。下面是一些代碼,工程就像一個普通的事件,使用委託對象,而不是玩:

Module Module1 
    Sub Main() 
     Dim obj As New Example 
     obj.AnEvent = New EventHandler(AddressOf Handler) 
     obj.Test() 
     Console.ReadLine() 
    End Sub 

    Sub Handler(ByVal sender As Object, ByVal e As EventArgs) 
     Console.WriteLine("got event") 
    End Sub 
End Module 

Class Example 
    Public AnEvent As EventHandler 
    Public Sub Test() 
     If AnEvent IsNot Nothing Then AnEvent(Me, EventArgs.Empty) 
    End Sub 
End Class 

但是千萬注意,此代碼的問題。其他一些代碼也可能會混淆AnEvent。就像替換它或將其設置回無。在大多數情況下,這是災難性的,首先訂閱事件的代碼將停止正常工作。

事件 VB.NET中的關鍵字可以防止發生這種情況。它包裝了委託對象,並使其他代碼無法訪問,而不是提供的關鍵字。與財產如何保護對領域的訪問有些類似。 AddHandler和RemoveHandler確保現有註冊不會消失。 RaiseEvent觸發事件,不需要檢查Nothing