我有多种不同的方法,我无法编辑:
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
我开始创建一个这样的类:
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)
有可能吗?我怎样才能获得这种效果/我应该使用哪种模式?
答案 0 :(得分:2)
How can I pass a Method that has some arguments
问题是创建和使用MyClassWrapper
的代码没有传入任何参数,并且由于Action
没有返回,如果你需要返回,它不是正确的选择。
该示例显示为每个方法创建一个新的对象包装器,这似乎效率低下。为简单起见,我将参数更改为您无权访问的类的基本类型:
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种不同的方法。我不确定它是否清楚地必须辨别出哪个方法被参数的顺序/类型调用。
直接将函数的地址传递给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)
如果在某个类/表单级别声明,fDel
委托可以设置一次。如果重新创建objSealed
,则代码将需要重置委托。特别是通用名称或准超载,命名的Delegate可以帮助您跟踪哪个是。
两者都相当麻烦,因为负担被消耗在代码上。
你也可以拥有包装"抓住"代表。在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)
稍微不那么累赘。你也可以让包装器设置所有这些并通过在构造函数中传递密封的类对象来保持它们:
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)