如何传递带有多个参数的方法作为另一个方法的参数 [英] How to pass a method with multiple parameters as argument of another method

查看:249
本文介绍了如何传递带有多个参数的方法作为另一个方法的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有多种无法编辑的方法:

I have multiple and different methods that I can't edit:

    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


问题是:


The problem is:

如何传递带有某些参数的Method并在ExecuteFunction中调用它们?我尝试使用Action,但是它不符合其定义和用法.

How can I pass a Method that has some arguments and recall them in ExecuteFunction? I tried using Action but it does not fit with its definition and usage.

例如,我想做这样的事情:

For example, I would like to do something like this:

Dim test1 = new MyWrapperClass(Test1)
test1.ExecuteFunction(1, "test1", true)

Dim test2 = new MyWrapperClass(Test2)
test2.ExecuteFunction(true, 0.34)

有可能吗?如何获得这种效果/应该使用哪种模式?

Is it possible? How can I get this effect / which pattern should I use?

推荐答案

How can I pass a Method that has some arguments

问题在于创建和使用MyClassWrapper isnt的代码不会传入任何参数,并且由于Action没有返回值,因此如果需要返回值,这不是正确的选择.

The problem is the code which creates and uses MyClassWrapper isnt passing in any arguments, and since Action has no return, it is not the right choice if you need the return.

该示例显示了为每种方法创建一个新的对象包装器,这似乎效率很低.为简单起见,我将您无权访问的类的参数更改为基本类型:

The example shows creating a new object wrapper for each method, which seems inefficient. For simplicity, I changed the arguments to basic types for the class you dont have access to:

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种不同的方法.我不确定必须辨别参数的顺序/类型正在调用哪种方法是否会增加清晰度.

The different names seems to indicate the target methods are not overloads, but MyWrapperClass seems to wants to interact with them as if they are by using the same name ExecuteFunction. Even though the question code is contrived for posting here, the CantEditClass is exposing 3 different methods. I am not sure it adds clarity to have to discern which method is being called by the order/type of arguments.

从字面上将函数的地址传递给Wrapper方法.为此,可以使用Func()声明包装方法,以定义链接到的方法:

Literally pass the address of the function to the Wrapper method. For this, the wrapper methods could be declared using Func() to define the method chained to:

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可以帮助您跟踪哪个是哪个.

The fDel delegate can be set once if declared at some class/form level. If objSealed is recreated, the code will need to reset the delegate. Especially with a generic name or quasi overload the named Delegate can help you keep track of which is which.

这两者都很麻烦,因为负担在使用代码上.

Both are rather cumbersome because the burden is put on the consuming code.

您还可以使包装器保留"委托.在Wrapper:

You could also have the wrapper "hold onto" the delegate. In 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)    

稍微麻烦些.您还可以通过在构造函数中传递密封的类对象,让包装器将所有这些设置并保留下来:

Slightly less cumbersome. You could also let the wrapper set all these up and hold onto them by passing the sealed class object in the constructor:

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可能会更聪明:

Smart Wrapper, No Delegates

Delegates may make sense if there is variation in which of these is invoked in conjunction with a Wrapper method. If not, the Wrapper could be a little smarter:

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

该代码可以轻松调用这两个版本:

The code can invoke either version easily:

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)   

这篇关于如何传递带有多个参数的方法作为另一个方法的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆