有时我们会有通过反射来动态构造泛型类型的需求,该如何实现呢?举个栗子,比如我们常常定义的泛型委托Func<in T, out TResult>,当T或TResult的类型需要根据程序上下文来确定时,也就是说我们的泛型委托类型是动态确定的,那么如何来构造呢?答案就是typeof(Func<,>).MakeGenericType(typeof(T), typeof(TResult))

一、先来看下Type.MakeGenericType的描述。

// C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\mscorlib.dll
namespace System
{
//
// 摘要:
// 替代由当前泛型类型定义的类型参数组成的类型数组的元素,并返回表示结果构造类型的 System.Type 对象。
//
// 参数:
// typeArguments:
// 将代替当前泛型类型的类型参数的类型数组。
//
// 返回结果:
// System.Type 表示的构造类型通过以下方式形成:用 typeArguments 的元素取代当前泛型类型的类型参数。
//
// 异常:
// T:System.InvalidOperationException:
// 当前的类型不表示泛型类型定义。也就是说, System.Type.IsGenericTypeDefinition 返回 false。
//
// T:System.ArgumentNullException:
// typeArguments 为 null。- 或 - 任何元素 typeArguments 是 null。
//
// T:System.ArgumentException:
// 中的元素数 typeArguments 不是当前的泛型类型定义中的类型参数的编号相同。- 或 - 任何元素 typeArguments 不满足当前的泛型类型的相应类型参数指定的约束。-
// 或 - typeArguments 包含的元素,是指针类型 (System.Type.IsPointer 返回 true),通过 ref 类型 (System.Type.IsByRef
// 返回 true),或 System.Void。
//
// T:System.NotSupportedException:
// 在基类中不支持调用的方法。派生类必须提供一个实现。
public virtual Type MakeGenericType(params Type[] typeArguments);
}

二、示例

通过MakeGenericType方法,从Func<T,TResult>泛型委托类型创建出特定类型Func<string,Object>的委托类型。

    class Program
{
static void Main(string[] args)
{
Console.WriteLine("\r\n--- 通过基本的泛型委托类型构造特定类型的委托类型。"); //创建一个类型对象,表示基本的泛型委托类型。
//要省略类型参数(但保留类型参数之间的逗号,使编译器能够推断出参数数量)。
Type generic = typeof(Func<,>);
DisplayTypeInfo(generic); //创建类型数组以替代泛型委托的类型参数,
//输入参数类型为string,输出参数类型为Object。
Type[] typeArgs = { typeof(string), typeof(Object) }; //创建特定类型的泛型委托类型对象
Type constructed = generic.MakeGenericType(typeArgs);
DisplayTypeInfo(constructed); //再通过typeof()直接创建一个类型对象
Type t = typeof(Func<String, Object>); Console.WriteLine("\r\n--- 比较两种方法得到的类型:");
Console.WriteLine("\t两种类型是否相等? {0}", t == constructed);
Console.WriteLine("\t两种类型的泛型类型定义是否相等? {0}",t.GetGenericTypeDefinition() == generic);
Console.Read();
}
private static void DisplayTypeInfo(Type t)
{
Console.WriteLine("\r\n{0}", t);
Console.WriteLine("\t是否泛型类型定义? {0}",t.IsGenericTypeDefinition);
Console.WriteLine("\t是否泛型类型? {0}",t.IsGenericType); Type[] typeArguments = t.GetGenericArguments();
Console.WriteLine("\t枚举类型参数 ({0}):", typeArguments.Length);
foreach (Type tParam in typeArguments)
{
Console.WriteLine("\t\t{0}", tParam);
}
}
}

输出

使用Type.MakeGenericType,反射构造泛型类型的更多相关文章

  1. Type.MakeGenericType 方法 (Type[]) 泛型反射

    替代由当前泛型类型定义的类型参数组成的类型数组的元素,并返回表示结果构造类型的 Type 对象. 命名空间:   System程序集:  mscorlib(mscorlib.dll 中) public ...

  2. Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法

    Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3 ...

  3. python 面向对象专题(六):元类type、反射、函数与类的区别、特殊的双下方法

    目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3. 函数与类的区别 4. 特殊的双下方法 1. 元类type type:获取对象 ...

  4. java学习:用反射构造bean

    先贴一些反射的基本知识:-------------------------------------------------------------------- 一.什么是反射:反射的概念是由Smit ...

  5. java 利用反射构造泛型类

    1.构造BaseDao泛型类 class BaseDao<T>{ private Class<T> entityClass; // 通过反射获取实际运行的精确类 public ...

  6. Java反射获取泛型类型

    本文链接:https://blog.csdn.net/hongxingxiaonan/article/details/49202613 在Java反射技术的应用中,取得一个类的成员.方法和构造函数相对 ...

  7. Java 反射 -- 获取泛型类型

    先写一个类: public class Demo03 { public void test01(Map<String, User> map, List<User> list) ...

  8. python---issubclass/type/isinstance/ 反射(内置函数getattr/delattr...)

    # 一 python面向对象-内置函数(issubclass(), type(), isinstance()) # issubclass 判断xxxx类是否是xxxx类的子类 class egg: p ...

  9. day17 isinstance type issubclass 反射

    1. issubclass,type,isinstance 1.issubclass 判断xxx是否yyy的子类 例: class Foo: pass class Bar(Foo): pass cla ...

随机推荐

  1. Axis2创建WebService服务端接口+SoupUI以及Client端demo测试调用

    第一步:引入axis2相关jar包,如果是pom项目,直接在pom文件中引入依赖就好 <dependency> <groupId>org.apache.axis2</gr ...

  2. python之正则表达式和re模块一

    摘要:正则表达式 re模块 一.正则表达式:只和字符串打交道,是一种用来约束字符串的规则 1.应用场景: 1,判断某一个字符串是否符合规则:注册页-判断手机号.身份证号 是否合法 注册某个账号的时候, ...

  3. 关于Qt的StyleSheet作用范围

    Qt的StyleSheet是很方便的一个设置各种控件风格形态的属性,但是默认的StyleSheet会作用于所有的子控件,容易带来麻烦,以下几种情况,可以限制作用范围 以QTextEdit为例,实体名为 ...

  4. C++: sprintf浮点数精度控制;

    错误的写法: char buf[100]; int num = 10; sprintf(buf, "%.2f", num); ///这种做法是不对的, 按照压栈顺序, 在压入num ...

  5. 使用catboost解决ML中高维度不平衡数据集挑战的解决方案

    python风控评分卡建模和风控常识(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005214003&am ...

  6. Numpy进阶操作

    目录 1. 如何获取满足条设定件的索引 2. 如何将数据导入和导出csv文件 3. 如何保存和加载numpy对象 4. 如何按列或行拼接numpy数组 5. 如何按列对numpy数组进行排序 6. 如 ...

  7. Redis扩展机制

    Redis扩展机制扫盲 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 关于Redis的Avalibility解决方案有很多,比如Twemproxy,Codis, 一.Twempro ...

  8. Docker:容器的四种网络类型 [十三]

    一.None类型 简介:不为容器配置任何网络功能,--net=none 1.创建容器 docker run -it --network none busubox:latest 2.功能测试 [root ...

  9. SpringBoot项目@RestController使用 redirect 重定向无效

    Spring MVC项目中页面重定向一般使用return "redirect:/other/controller/";即可. 而Spring Boot当我们使用了@RestCont ...

  10. React 记录(5)

    React文档:https://www.reactjscn.com/docs/state-and-lifecycle.html 慢慢学习:对照教程文档,逐句猜解,截图 React官网:https:// ...