我有一个方法,将一系列操作作为参数。此数组中的操作应始终需要1个参数,但参数类型可能不同。
该方法应在调用之前检查操作所需的参数类型。如果需要String
,则参数将为"text"
。如果需要Integer
,则参数将为123
。
这是我尝试过的:
Sub MethodA(ParamArray actions() As Action(Of Object))
For Each action() As Action(Of Object) In actions
If action.Method.GetParameters()(0).ParameterType = GetType(String) Then
action("text")
ElseIf action.Method.GetParameters()(0).ParameterType = GetType(Integer) Then
action(123)
ElseIf ...
' You get the point.
End If
Next
End Sub
但是,action.Method.GetParameters()(0).ParameterType
总是Object
,可能是因为MethodA
的参数数组只需要Action(Of Object)
。
由于我的代码不起作用,我还能尝试什么?如何找到真正所需的操作类型?
注意:我可以使用Try ... Catch
,但我想确定不需要调用方法所需的参数类型。
修改:我发现我不理解Action(Of T)
和AddressOf
的行为,这可能与我的问题有关。请参阅以下代码:
Sub MyStringMethod(s As String)
' Do something
End Sub
MethodA(AddressOf MyStringMethod) ' Compiles
Dim stringAction As Action(Of String) = AddressOf MyStringMethod
MethodA(stringAction) 'Does not compile
这有什么不同? AddressOf
会生成Action(Of Object)
吗?
答案 0 :(得分:0)
问题是没有办法将Action(Of Object)
变量设置为Action(Of String)
或Action(Of Integer)
对象,例如:
Dim actions(2) As Action(Of Object)
'The following lines will not compile
actions(0) = New Action(Of String)(AddressOf MyStringMethod)
actions(0) = New Action(Of Integer)(AddressOf MyIntegerMethod)
所以问题不在于您检查类型的位置。问题是你首先不能将任何其他类型传递给方法,那么该方法怎么可能知道呢?
您需要通过创建包装类来传递每个操作的类型,例如:
Public Class MyAction
Public Sub New(ByVal action As Action(Of Object), ByVal parameterType As Type)
_action = action
_type = Type
End Sub
Public ReadOnly Property Action() As Action(Of Object)
Get
Return _action
End Get
End Property
Private _action As Action(Of Object)
Public ReadOnly Property Type() As Type
Get
Return _type
End Get
End Property
Private _type As Type
End Class
或者,如果数组中的所有项都采用相同的参数,那么您可以要求将类型作为方法的参数,例如:
Sub MethodA(ParamArray actions() As Action(Of Object), parameterType As Type)
'...
End Sub
<强>更新强>
根据后续对话,您需要做的只是使用基本Delegate
类型而不是Action(Of Object)
类型。例如:
Sub MethodA(ParamArray actions() As [Delegate])
'...
End Sub
但是,通过这样做,您允许传递具有其他类型签名的代理,例如,它将允许Function
而不是Sub
,或者方法为零参数或参数太多,而不是一个参数。因此,您可能需要在内部进行一些额外的检查,以确保代理的签名符合您的期望。