我在通用类中有一个事件
Public class SomeClass
Public Event ChangeEvent(oldValue As T, newValue As T)
' some code..
End Class
我有一个复杂的方法,我传递Action(Of T)
,它应该被添加到事件中,然后再次删除。它看起来像下面这样:
Public Sub SomeSub(listener As Action(Of T, T)
AddHandler ChangeEvent, listener
' some code
RemoveHandler ChangeEvent, listener
End Sub
但是在这两行上编译器都给出了以下错误:
'Action(Of T,T)'类型的值无法转换为'ChangeEventHandler'。
以下有效,但我无法删除处理程序,因为它是lambda表达式。
Public Sub SomeSub(listener As Action(Of T, T)
AddHandler ChangeEvent, Sub(x, y) listener(x, y)
End Sub
是否有一个解决方案不涉及我将lambda存储为成员?请注意,我无法更改活动。我只控制添加侦听器的方法。
答案 0 :(得分:1)
最好是显式声明事件处理程序委托,而不是让Visual Basic隐式地执行它:
Public Class SomeClass(Of T)
Public Delegate Sub ChangeEventHandler(oldValue As T, newValue As T)
Public Event ChangeEvent As ChangeEventHandler
' some code..
End Class
通过这种方式,您可以将委托指定为方法的参数,从而为编译器提供正确的签名,并且您可以添加和删除它:
Public Sub SomeSub(listener As ChangeEventHandler)
AddHandler ChangeEvent, listener
' some code...
RemoveHandler ChangeEvent, listener
End Sub
现在你和编译器都很开心! :)
答案 1 :(得分:0)
它实际上是这样的:
expect(mockService.coolMethod).ToHaveBeenCalled();
// or
mockService.coolMethod.and.returnValue('I am so cool');
这将添加处理程序,并在事件执行后立即将其删除。因此,lambda中的代码将只执行一次。
诀窍是要单独声明一个处理程序,因为在lambda中,您需要引用该变量以删除该处理程序。
您根本不需要保留任何成员变量,运行时将为您存储封装的变量。
但是,您必须确保该事件确实被触发(至少一次)。如果不是这样,则可能会导致内存泄漏,因为事件处理程序永远不会删除。