使用反射,运行时执行泛型方法

背景:有一个泛型类,其中一个方法是泛型方法

Public Class GenericClass(Of T)
    'This is not a generic method
    Public Sub Swap(ByRef item1 As T, ByRef item2 As T)
        Dim temp As T = item1
        item2 = item1
        item1 = temp
    End Sub
    'This ia a generic method and a generic method definition
    Public Sub Swap(Of U)(ByRef item1 As U, ByRef item2 As U)
        Dim temp As U = item1
        item2 = item1
        item1 = temp
    End Sub

    Public Function GenericMethod(Of M)(ByVal item1 As M) As String
        Return String.Format("You Passed in {0}", item1)
    End Function

End Class
 

现在的需求是,希望运用反射,在运行时,执行GenericMethod()方法

首先,提供一个显示泛型方法相关信息的方法

 Private Sub DisplayGenericMethodInfo(ByVal mi As MethodInfo)
        AddToResults(
"{0}"
, mi)

       
Dim indent1 As String
= vbTab
       
Dim indent2 As String
= vbTab & vbTab

        AddToResults(
"{0} Is generic method definition :{1}"
, indent1, mi.IsGenericMethodDefinition)
        AddToResults(
"{0} Is generic method {1}"
, indent1, mi.IsGenericMethod)
       
'获取一个值,该值指示当前Type对象是否具有尚未被特定类型替换的类型参数
       
AddToResults("{0} Includes unassigned generic parameters:{1}"
, indent1, mi.ContainsGenericParameters)
       
' if this is a generic method,displap its type arguments.
       
If mi.IsGenericMethod
Then
           
'返回表示泛型类型的类型实参或泛型类型定义的类型形参的Type对象的数组
           
Dim args As Type
() = mi.GetGenericArguments()
            AddToResults(
"{0} Type arguments({1}):"
, indent2, args.Length)

           
For Each argType As Type In
args
               
'IsGenericParameter is true only for generic type parameters
               
If argType.IsGenericParameter
Then
                   
AddToResults("{0}Parameters:{1}"
, indent2, argType)
                   
'当Type对象表示泛型类型或泛型方法的类型参数时,
                    '获取类型参数在声明它的泛型类型或方法的类型参数列表中位置
                   
AddToResults("{0}Parameters:{1}"
, indent2, argType.GenericParameterPosition)

                    AddToResults(
"{0}Declaring method:{1}"
, indent2, argType.DeclaringMethod)
               
Else
                   
AddToResults("{0}{1}"
, indent2, argType)
               
End If
            Next

        End If
       
AddToResults()
   
End Sub

请注意上面代码中的关于判断一个泛型参数是泛型类型的参数,还是泛型方法的参数。它可能来自一个您正在检查的类型,也可能来自一个封闭类型,或者来自一个泛型方法。您如何确定他的来源?

首先,检查类型的DeclaringMethod属性。如果该值不是nothing,它就会是MethodInfo实例,您就知道该类型参数来自一个泛型方法,并且MethodInfo的IsGenericMethodDefinition属性将返回True.如果源不是一个泛型方法,DeclaringMethod属性就会返回Nothing,此时您可以检索DeclaringType属性。同时,只有在类型的IsGenericParameter属性返回True时,才能检索DeclaringMethod属性;否则会引发异常。

现在开始实现要求:

    Private Sub CallGenericMethodGivenGenericMethodDefinition()

        Dim type1 As Type = GetType(GenericClass(Of Integer))
        Dim mi As MethodInfo = type1.GetMethod("GenericMethod")
        DisplayGenericMethodInfo(mi)

        Dim argTypes() As Type = {GetType(String)}
        Dim miConstructed As MethodInfo = mi.MakeGenericMethod(argTypes)
        DisplayGenericMethodInfo(miConstructed)

        'invoke the method ,createing an instance of the generic class first
        Dim host As New GenericClass(Of Integer)

        'supply the method parameters,and then invoke the method:
        Dim args() As Object = {"test value"}
        AddToResults("{0}", miConstructed.Invoke(host, args))
        AddToResults()

        'construct another version of the same
        'generic method ,this time taking an ineger as the parameter
        argTypes(0) = GetType(Integer)
        miConstructed = mi.MakeGenericMethod(argTypes)
        DisplayGenericMethodInfo(miConstructed)

        'Supply the method parameters,and then invoke the method:
        args(0) = 13
        AddToResults("{0}", miConstructed.Invoke(host, args))


    End Sub
posted @ 2013-02-27 15:44  暴走小白  阅读(422)  评论(0编辑  收藏  举报