zoukankan      html  css  js  c++  java
  • 使用反射,运行时执行泛型方法

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

    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
  • 相关阅读:
    日志框架1---多种日志门面和日志实现初步了解(转载)
    @Autowired 与@Resource的区别(转)
    Spring 之jdbc模板(JdbcTemplate与NamedParameterJdbcTemplate)
    springMVC中的Controller里面定义全局变量
    spring批量更新数据 ---- BatchPreparedStatementSetter
    easyui树查找
    根据ID和parentID利用Java递归获取全路径名称
    一个统一将数据转换为JSON的方法
    上传图片并限制图片格式和大小
    js上传文件(图片)的格式和大小限制
  • 原文地址:https://www.cnblogs.com/RealAlex/p/2935286.html
Copyright © 2011-2022 走看看