我有一个“总是”按顺序运行步骤A,C,D的算法。
我想允许一种方法来运行A,B,C,D,其中B可以是多种方法。 C,D“应该”不受影响,但我无法并行化。它只是写入文件。
无论如何,我对委托知之甚少,并使用AddressOf来挂钩事件处理程序。
所以我只想创建一个不包含“地址”或代表的数组或集合。
这甚至可能吗?
这是'最好'的方式吗?我知道如何强制使用对象的行为,但我希望重用已经内置于VB,.NET的任何机制。
戴恩
答案 0 :(得分:1)
这不是您经常看到的内容,但您可以组合委托,以便单个委托变量在调用时调用多个函数。
Dim midAction As Action(Of String) = AddressOf Console.WriteLine
Dim m1 As New IO.StreamWriter(New IO.MemoryStream())
m1.AutoFlush = True
Dim m2 As New IO.StreamWriter(New IO.MemoryStream())
midAction = CType([Delegate].Combine(New Action(Of String)(AddressOf Console.WriteLine),
New Action(Of String)(AddressOf m1.WriteLine),
New Action(Of String)(Sub(s)
m2.WriteLine(s)
m2.Flush()
End Sub)),
Action(Of String))
midAction("test")
这里最大的问题是Delegate.Combine
的无类型使得所有的演员阵容变得必要。
IEnumerable
代表也可以工作,更强烈地传达您想要调用多个功能。
根据您的描述,我认为我会坚持使用单个委托参数,因为它似乎更适合参数的语义。当调用者有多个需要在中间调用的函数时,可以进行组合。
答案 1 :(得分:1)
您可以简单地使用事件来存储和调用多个方法。事件基本上是简化的多播代理,因此您不必使用Delegate.Combine
。缺点是您的方法将无法返回类型。
这也是使用多播委托的另一种方法。此示例假定您希望从方法返回值。如果你不需要这个,你就不必循环使用这些方法;你可以使用myMethods.Invoke
。
'the methods will be stored here
Private _MyMethods As [Delegate]
'this is here to show the signature of the methods
Public Delegate Function MyMethod(ByVal input As String) As String
Public Sub AddMethod(ByVal method As MyMethod)
_MyMethods = [Delegate].Combine(_MyMethods, method)
End Sub
Public Sub RemoveMethod(ByVal method As MyMethod)
_MyMethods = [Delegate].Remove(_MyMethods, method)
End Sub
Public Sub InvokeMethods(ByVal input As String)
If _MyMethods Is Nothing Then Return
Dim myMethods As MyMethod = DirectCast(_MyMethods, MyMethod)
'since you'll want the return value of each methods, loop through the methods
For Each method As MyMethod In myMethods.GetInvocationList()
Dim value As String = method.Invoke(input)
'TODO: something with the value
Next
End Sub
作为上述调用代码的另一种替代方法,您可以使用Delegate.DynamicInvoke
方法来不必转换委托。但是,这将使用后期绑定,并且在函数的情况下,无论如何都需要返回值。