zoukankan      html  css  js  c++  java
  • 一些支离破碎的泛型反射技巧

    本文为一些泛型反射技巧的简单罗列,为日后的文章做准备。
    1、如何获得一个封闭构造类型(closed constructed type)的Type对象?
    假设有如下的类型:
    class TestType<T>
    class TestType<T, U>
    如果要获得封闭构造类型的Type对象,那么只需要用C#的typeof运算符,或者VB的GetType运算符作用于具体类型即可:
    //C#
    Type t1 = typeof(TestType<int>);
    'VB
    Dim t2 As Type = GetType(TestType(Of String))

    2、如何获取一个泛型类型(generic type)的Type对象?
    所谓泛型类型,就是有类型参数,但类型参数还未指定的原始定义。我们不能用TestType<T>这样的语法,因为T在我们的上下文中不存在。这时,可以用空的尖括号(C#)或空的Of语句(VB)来获取。
    Type t1 = typeof(TestType<>);
    Type t2 
    = typeof(TestType<,>);
    Dim t1, t2 As Type
    t1 
    = GetType(TestType(Of ))
    t2 
    = GetType(TestType(Of ,))
    注意,我们可以用逗号来区别类型参数的个数。这就表明,泛型类型只能按类型参数的多少来重载,而不管有何种约束之类。这里获得的Type,就是类型参数未指定的泛型类型。

    3、如何从构造类型的Type对象生成泛型类型的Type对象?
    Type类的新增方法可以做到。
    //C#
    Type ct = typeof(List<int>);

    //Get generic type definition
    Type gt = ct.GetGenericTypeDefinition();

    4、如何获取类型参数的Type对象?
    泛型类型的T, U等类型参数,以及运行中的实际取值,都是可以从Type对象获取的。
    'VB
    Dim t As Type = GetType(List(Of Integer))

    'Get the generic arguments, an array
    Dim typeArgs As Type() = t.GetGenericArguments()
    'Get the first argument: Integer in this case
    Dim tArg0 As Type = typeArgs(0)

    5、从泛型类型Type对象生成构造类型的Type对象。
    通常可以用来从一种构造类型生成另一种构造类型
    //C#
    Type ct = typeof(List<int>);
    Type gt 
    = ct.GetGenericTypeDefinition();

    //Make another constructed type
    //The List<string> in this case
    Type ct2 = gt.MakeGenericType(typeof(string));

    6、如何取一个开放构造类型(open constructed type)的Type对象?
    开放构造类型是最难处理的一个,因为他们的类型参数已经指定,但没有指定为具体类型,而是指定为其他泛型类型的类型参数。这种类型在进行反射重载选取以及反射发出(Reflection Emit)操作的时候尤为重要。我们的手法就是,先从宿主泛型类型的定义中获取类型参数的类型,然后再建造出开放构造类型。这里,我们获得List<T>的构造函数的参数,IEnumerable<T>的类型,注意这里的T是List<T>所定义的,而不是泛型IEnumerable<T>自己的类型参数
    'The generic type of List(Of T)
    Dim tlist As Type = GetType(List(Of ))

    'Get the "T" of List(Of T)
    Dim typeParam As Type = tlist.GetGenericArguments()(0)

    'the generic type of IEnumerable(Of T)
    Dim tienum As Type = GetType(IEnumerable(Of ))

    'make the open constructed type
    Dim tienumOpen As Type = tienum.MakeGenericType(typeParam)

    '只有用这种方法获得开放构造类型
    '
    你才能用这个语法获得真正想要的构造函数定义
    '
    因为构造函数定义里IEnumerable(Of T)是一个开放构造类型
    Dim c As ConstructorInfo = _
        tlist.GetConstructor(
    New Type() {tienumOpen})

    大家可以回去结合试验理解这些用法。
  • 相关阅读:
    photoshop--图像大小(分辨率和宽高)
    Arduino--单向倾斜开关
    禁止google浏览器http链接强制跳转为https
    属性缓存_使用ConcurrentDictionary替代Hashtable对多线程的对象缓存处理
    .Net(windows服务器)清理缓存数据的几个方法
    【西天取经】(升级.net5)用了一整天才把项目从.netcoreapp3.1升级到.net5(转载)
    在Debian 9 vim中启用鼠标复制粘贴
    将数据批量插入SQL Server
    shell 脚本中 在grep -E '($wo|$ni|$ta)' 这里面用变量
    kubernetes 重启的几种方法
  • 原文地址:https://www.cnblogs.com/Ninputer/p/415458.html
Copyright © 2011-2022 走看看