2012-12-03 52 views
0

我有一个方法,将一组操作作为参数。此数组中的操作始终需要1个参数,但参数类型可能不同如何查找Action的参数类型(使用反射)?

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

你还能尝试什么?回到绘图板并检查这是否是解决您尝试解决的任何问题的最佳方法。 – Jamiec

+0

@Jamiec:我知道我在写不干净的代码,但不幸的是我正在设计一个设计不佳的库。我上面解释的似乎是解决我的问题的唯一可能性。 –

+0

@ L.B:是的,但这并不能解决我的问题。如果我没有检查参数类型并调用'Invoke',那么当我使用错误的参数类型时,我会得到一个exeption,这正是我想要避免的。 –

回答

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 

或者,如果阵列中的所有项目采取同样的参数,那么你可以问基于后续convers

Sub MethodA(ParamArray actions() As Action(Of Object), parameterType As Type) 
    '... 
End Sub 

UPDATE

:类型作为参数传递给你的方法,例如您需要做的只是使用基本类型Delegate而不是Action(Of Object)类型。例如:

Sub MethodA(ParamArray actions() As [Delegate]) 
    '... 
End Sub 

然而,通过这样做,你与其他类型的签名传递中,例如允许的代表,这将允许Function而不是Sub,或零个参数的方法,或者参数太多,而不是一个。所以,你可能需要在里面做一些额外的检查,以确保代表的签名是你期望的。

+0

我不知道如果我做错了什么,但这些行编译得很好。 –

+0

@RuudLenders有趣...我在VS2005中测试它,但是不允许。它说“类型Action(Of String)的值不能转换为Action(Of Object)”。我想知道这是在VB的更新版本中变得更加灵活,还是在“Option Infer On”时允许。 –

+0

糟糕,我的不好。这些行不会编译。奇怪,为什么你不能将'Action(Of String)'赋给'Action(Of Object)',而你可以将它作为参数传递给'MethodA',它需要'Action(Of Object)'? –

相关问题