2012-12-03 92 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)'? –

相關問題