好吧,也许我不应该在第一个地方创建一个新的线程。但是,我在Hans Passant的建议(在另一个线程中)做了这个线索。
Passant对我上面的问题的直接评论非常有帮助。下面是一段代码,说明了情况:
Imports System
Imports System.Reflection
Module M
Sub Main()
AddHandler C1.Bang, AddressOf SomeAction
C1.Test()
AddHandler C2.Boom, AddressOf SomeAction
C2.Test()
' Check which GetRaiseMethod find something
Dim bangRaiseAccessor As MethodInfo = GetType(C1).GetEvent("Bang").GetRaiseMethod(True)
Dim boomRaiseAccessor As MethodInfo = GetType(C2).GetEvent("Boom").GetRaiseMethod(True)
Console.WriteLine("M: GetRaiseMethod(True) for C1.Bang: {0}",
If(bangRaiseAccessor, DirectCast("<none>", Object))
)
Console.WriteLine("M: GetRaiseMethod(True) for C2.Boom: {0}",
If(boomRaiseAccessor, DirectCast("<none>", Object))
)
End Sub
Private Sub SomeAction()
Console.WriteLine("M: Inside 'SomeAction'.")
End Sub
End Module
Class C1
' auto-event; backing delegate type, backing field and accessor methods are compiler-generated
Shared Event Bang()
Private Shared Sub OnBang() Handles Me.Bang
Console.WriteLine("C1: Inside 'OnBang'.")
End Sub
Shared Sub Test()
Console.WriteLine("C1: Test firing event Bang.")
RaiseEvent Bang()
Console.WriteLine("C1: Test finished.")
End Sub
End Class
Class C2
Shared Custom Event Boom As Action
AddHandler(value As Action)
Console.WriteLine("C2: Inside custom AddHandler accessor, 'value' contains '{0}'.",
If(value = Nothing, "<none>", value.Method.ToString())
)
' TODO: use parameter, for example aggregate "value" in field with delegate combination
End AddHandler
RemoveHandler(value As Action)
Console.WriteLine("C2: Inside custom RemoveHandler accessor, 'value' contains '{0}'.",
If(value = Nothing, "<none>", value.Method.ToString())
)
' TODO: use parameter, for example subtract "value" from field with delegate removal
End RemoveHandler
RaiseEvent()
Console.WriteLine("C2: Inside custom RaiseEvent accessor.")
End RaiseEvent
End Event
Private Shared Sub OnBoom() Handles Me.Boom
Console.WriteLine("C2: Inside 'OnBoom'.")
End Sub
Shared Sub Test()
Console.WriteLine("C2: Test firing event Boom.")
RaiseEvent Boom()
Console.WriteLine("C2: Test finished.")
End Sub
End Class
人们得到的输出:
C1: Test firing event Bang.
C1: Inside 'OnBang'.
M: Inside 'SomeAction'.
C1: Test finished.
C2: Inside custom AddHandler accessor, 'value' contains 'Void OnBoom()'.
C2: Inside custom AddHandler accessor, 'value' contains 'Void SomeAction()'.
C2: Test firing event Boom.
C2: Inside custom RaiseEvent accessor.
C2: Test finished.
M: GetRaiseMethod(True) for C1.Bang:
M: GetRaiseMethod(True) for C2.Boom: Void raise_Boom()
结论:
- “自动”
Event
不会有加薪访问器方法,并GetRaiseMethod
将返回Nothing
- 一个
Custom Event
需要一个加薪访问方法RaiseEvent(...)
,和GetRaiseMethod(True)
返回它的反射表示(MethodInfo
)
- 订阅事件(
Custom
与否)发生在运行时,无论您订阅与语法AddHandler C1.Bang, AddressOf SomeAction
(在这种情况下,达到此语句时的认购情况,当然),或您订阅的语法Private Shared Sub OnBang() Handles Me.Bang
(在这种情况下,认购早期发生的,任何AddHandler
语句运行之前,肯定任何使用Event Bang
之前)
您没有发布您的代码。感谢downvote顺便说一句,可爱,总是很高兴提醒你,没有写出正确的代码是我的问题。使用Event声明中的Custom关键字,以便您可以声明RaiseEvent访问器。使用BindingFlags.NonPublic | BindingFlags.Instance在GetRaiseMethod()调用中。 –