如何将具有多个参数的方法作为另一个方法的参数传递
How to pass a method with multiple parameters as argument of another method
我有多种不同的方法无法编辑:
Public Function Test1(A As Integer, B As String, C As Boolean) As Boolean
Public Function Test2(A As Boolean, B As Double) As DataTable
Public Function Test3(A As String) As Integer
我开始像这样创建 class:
Public Class MyWrapperClass
Dim _method As Action()
Public Sub New(Method As Action())
_method = Method
End Sub
Public ExecuteFunction()
_method()
' And do something with the result
End Function
End Class
问题是:
如何传递具有一些参数的 Method
并在 ExecuteFunction
中调用它们?我尝试使用 Action
但它不符合其定义和用法。
例如,我想做这样的事情:
Dim test1 = new MyWrapperClass(Test1)
test1.ExecuteFunction(1, "test1", true)
Dim test2 = new MyWrapperClass(Test2)
test2.ExecuteFunction(true, 0.34)
可能吗?我怎样才能得到这种效果/我应该使用哪种模式?
How can I pass a Method that has some arguments
问题是创建和使用 MyClassWrapper
的代码没有传入任何参数,并且由于 Action
没有 return,如果您需要return.
该示例显示为每个方法创建一个新的对象包装器,这似乎效率低下。为简单起见,我将参数更改为您无法访问的 class 的基本类型:
Public Function Test1(A As Integer, B As String, C As Boolean) As Int32
Public Function Test2(A As Boolean, B As Double) As String
Public Function Test3(A As String) As Integer
不同的名称似乎表明目标方法是不是重载,但MyWrapperClass
似乎想与他们就好像他们使用相同的名字 ExecuteFunction
。尽管问题代码是为了在此处发布而设计的,但 CantEditClass
公开了 3 种不同的方法。我不确定必须辨别参数 order/type 调用了哪个方法是否会增加清晰度。
基本答案
直接将函数的地址传递给Wrapper方法。为此,可以使用 Func()
声明包装器方法以定义链接到的方法:
Public Function Test1Exec(f As Func(Of Int32, String, Boolean, Int32), a As Int32) As Int32
Dim n As Int32 = f(a, "foo", False)
End Function
用法:
Private wrapper As Wrapper
Private objSealed As CantEditClass
...
wrapper = New Wrapper
objSealed = New CantEditClass
...
Dim b = wrapper.Test1Exec(AddressOf objSealed.Test1, 6)
声明一个委托以供重用
' declared with the other objects
Private fDel As Func(Of Int32, String, Boolean, Int32)
...
' initialized:
fDel = AddressOf objSealed.Test1
...
Dim b = wrapper.Test1Exec(fDel, 6)
如果在某个 class/form 级别声明,fDel
委托可以设置一次。如果重新创建 objSealed
,代码将需要重置委托。特别是对于通用名称或准重载,命名委托可以帮助您跟踪哪个是哪个。
两者都比较麻烦,因为负担放在了消费代码上。
委托为包装类型
您还可以让包装器 "hold onto" 委托。在 Wrapper
:
Public Delegate Function Test1Delegate(a As Int32, b As String, c As Boolean) As Int32
Public Function Test1aExec(f As Test1Delegate, a As Int32) As Int32
Dim n As Int32 = f(a, "foo", False)
End Function
用法:
Dim fDel2 As Wrapper.Test1Delegate = AddressOf objSealed.Test1
...
b = wrapper.Test1aExec(fDel2, 6)
稍微不那么麻烦。您还可以让包装器设置所有这些并通过在构造函数中传递密封的 class 对象来保留它们:
Private Delegate Function Test2Delegate(a As Boolean, b As Double) As String
Private Test2D As Test2Delegate
Private Delegate Function Test3Delegate(a As String) As Integer
Private Test3D As Test3Delegate
Public Sub New(target As CantEditClass)
' internal assignment
Test2D = AddressOf target.Test2
Test3D = AddressOf target.Test3
End Sub
智能包装器,无委托
如果与 Wrapper
方法一起调用其中的委托存在差异,则委托可能有意义。如果不是,Wrapper
可能更聪明一点:
Public ReadOnly TargetObject As CantEditClass
' alternatively pass the object
' if the calling code needs it for something like events
Public Sub New()
' internal mapping
Dim TargetObject = New CantEditClass
End Sub
Public Function Text1Ex(arg1 As Int32, arg2 As String, arg3 As Boolean) As Int32
Dim result = TargetObject.Test1(arg1, arg2, arg3)
' work with result
Return If(arg3, arg1, -arg1)
End Function
代码可以轻松调用任一版本:
MyWrap = New Wrapper()
' call EXtended wrapper version
Dim result = MyWrap.Text1Ex(42, "ziggy", False)
' invoke the native version:
result = MyWrap.TargetObject.Test1(42, "zalgo", True)
我有多种不同的方法无法编辑:
Public Function Test1(A As Integer, B As String, C As Boolean) As Boolean
Public Function Test2(A As Boolean, B As Double) As DataTable
Public Function Test3(A As String) As Integer
我开始像这样创建 class:
Public Class MyWrapperClass
Dim _method As Action()
Public Sub New(Method As Action())
_method = Method
End Sub
Public ExecuteFunction()
_method()
' And do something with the result
End Function
End Class
问题是:
如何传递具有一些参数的 Method
并在 ExecuteFunction
中调用它们?我尝试使用 Action
但它不符合其定义和用法。
例如,我想做这样的事情:
Dim test1 = new MyWrapperClass(Test1)
test1.ExecuteFunction(1, "test1", true)
Dim test2 = new MyWrapperClass(Test2)
test2.ExecuteFunction(true, 0.34)
可能吗?我怎样才能得到这种效果/我应该使用哪种模式?
How can I pass a Method that has some arguments
问题是创建和使用 MyClassWrapper
的代码没有传入任何参数,并且由于 Action
没有 return,如果您需要return.
该示例显示为每个方法创建一个新的对象包装器,这似乎效率低下。为简单起见,我将参数更改为您无法访问的 class 的基本类型:
Public Function Test1(A As Integer, B As String, C As Boolean) As Int32
Public Function Test2(A As Boolean, B As Double) As String
Public Function Test3(A As String) As Integer
不同的名称似乎表明目标方法是不是重载,但MyWrapperClass
似乎想与他们就好像他们使用相同的名字 ExecuteFunction
。尽管问题代码是为了在此处发布而设计的,但 CantEditClass
公开了 3 种不同的方法。我不确定必须辨别参数 order/type 调用了哪个方法是否会增加清晰度。
基本答案
直接将函数的地址传递给Wrapper方法。为此,可以使用 Func()
声明包装器方法以定义链接到的方法:
Public Function Test1Exec(f As Func(Of Int32, String, Boolean, Int32), a As Int32) As Int32
Dim n As Int32 = f(a, "foo", False)
End Function
用法:
Private wrapper As Wrapper
Private objSealed As CantEditClass
...
wrapper = New Wrapper
objSealed = New CantEditClass
...
Dim b = wrapper.Test1Exec(AddressOf objSealed.Test1, 6)
声明一个委托以供重用
' declared with the other objects
Private fDel As Func(Of Int32, String, Boolean, Int32)
...
' initialized:
fDel = AddressOf objSealed.Test1
...
Dim b = wrapper.Test1Exec(fDel, 6)
如果在某个 class/form 级别声明,fDel
委托可以设置一次。如果重新创建 objSealed
,代码将需要重置委托。特别是对于通用名称或准重载,命名委托可以帮助您跟踪哪个是哪个。
两者都比较麻烦,因为负担放在了消费代码上。
委托为包装类型
您还可以让包装器 "hold onto" 委托。在 Wrapper
:
Public Delegate Function Test1Delegate(a As Int32, b As String, c As Boolean) As Int32
Public Function Test1aExec(f As Test1Delegate, a As Int32) As Int32
Dim n As Int32 = f(a, "foo", False)
End Function
用法:
Dim fDel2 As Wrapper.Test1Delegate = AddressOf objSealed.Test1
...
b = wrapper.Test1aExec(fDel2, 6)
稍微不那么麻烦。您还可以让包装器设置所有这些并通过在构造函数中传递密封的 class 对象来保留它们:
Private Delegate Function Test2Delegate(a As Boolean, b As Double) As String
Private Test2D As Test2Delegate
Private Delegate Function Test3Delegate(a As String) As Integer
Private Test3D As Test3Delegate
Public Sub New(target As CantEditClass)
' internal assignment
Test2D = AddressOf target.Test2
Test3D = AddressOf target.Test3
End Sub
智能包装器,无委托
如果与 Wrapper
方法一起调用其中的委托存在差异,则委托可能有意义。如果不是,Wrapper
可能更聪明一点:
Public ReadOnly TargetObject As CantEditClass
' alternatively pass the object
' if the calling code needs it for something like events
Public Sub New()
' internal mapping
Dim TargetObject = New CantEditClass
End Sub
Public Function Text1Ex(arg1 As Int32, arg2 As String, arg3 As Boolean) As Int32
Dim result = TargetObject.Test1(arg1, arg2, arg3)
' work with result
Return If(arg3, arg1, -arg1)
End Function
代码可以轻松调用任一版本:
MyWrap = New Wrapper()
' call EXtended wrapper version
Dim result = MyWrap.Text1Ex(42, "ziggy", False)
' invoke the native version:
result = MyWrap.TargetObject.Test1(42, "zalgo", True)