0

我有一个将一系列动作作为参数的方法。此数组中的操作应始终需要 1 个参数,但参数类型可以不同

该方法应该在调用它之前检查一个动作需要什么类型的参数。如果它需要 a 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)?

4

1 回答 1

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

但是,通过这样做,您允许传入具有其他类型签名的委托,例如,它将允许 aFunction而不是 a Sub,或者具有零参数的方法,或者参数太多而不是恰好一个。因此,您可能需要在内部进行一些额外检查,以确保委托的签名是您所期望的。

于 2012-12-03T12:45:29.160 回答