我在問具體的VB.NET,但我想象一般原則在其他語言中是一樣的。我認爲一個事件是.NET中的一流概念,但從reflection看來,它只是一個特定的方法,它在事件引發時被調用。如何實施事件
- 如何
AddHandler
和RemoveHandler
修改方法動態(據我所知,事件pre-日期DynamicMethod
S' - 如何
RaiseEvent
調用的方法? - 爲什麼
AddHandler
,RemoveHandler
,並RaiseEvent
實現陳述而不是方法?
我在問具體的VB.NET,但我想象一般原則在其他語言中是一樣的。我認爲一個事件是.NET中的一流概念,但從reflection看來,它只是一個特定的方法,它在事件引發時被調用。如何實施事件
AddHandler
和RemoveHandler
修改方法動態(據我所知,事件pre-日期DynamicMethod
S'RaiseEvent
調用的方法?AddHandler
,RemoveHandler
,並RaiseEvent
實現陳述而不是方法?不,一個事件只是兩個或三個方法的組合(「raise」部分是可選的),方法與屬性是一個或兩個方法的組合相同。
AddHandler
和RemoveHandler
根本不修改方法。他們只是調用事件的「添加」和「刪除」部分,這些部分是實現部分的一部分。
通常情況下,事件通過對具有適當委託類型的字段的引用來實現,其中Delegate.Combine
和Delegate.Remove
用於執行適當的操作。 (字段值將被更改 - 請記住,委託類型是不可變的。)引發事件僅包含調用委託。
至於爲什麼AddHandler
等是單獨的語句類型 - 如果它們是方法,參數是什麼?有些事情必須提及「事件」。基本上,AddHandler
語句對應於適當的事件「add」方法,就像屬性獲取對應於適當的屬性「get」方法一樣。你可以用反射做到這一點,通過EventInfo.AddHandler
。
請參閱我的article on delegates and events瞭解更多詳情,這可能有所幫助 - 它來自C#背景,但其原理顯然是相同的。
事件只是一個代表。下面是一些代碼,工程就像一個普通的事件,使用委託對象,而不是玩:
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。
這是否意味着'RaiseEvent SomeEvent'和'SomeEvent()'具有相同的影響(其中'SomeEvent'被聲明爲'Public Event SomeEvent As Action')。在VS2010中使用'SomeEvent()'語法給我一個編譯錯誤,我必須使用'RaiseEvent'語法。 – 2013-04-29 14:52:22
@ just.another.programmer:嗯,我相信如果你能夠得到這個值,他們會有同樣的效果,但是這是VB方面的一個細節,我不太熟悉。 – 2013-04-29 14:54:54