使用Type.MakeGenericType,反射构造泛型类型
有时我们会有通过反射来动态构造泛型类型的需求,该如何实现呢?举个栗子,比如我们常常定义的泛型委托
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,反射构造泛型类型的更多相关文章
- Type.MakeGenericType 方法 (Type[]) 泛型反射
替代由当前泛型类型定义的类型参数组成的类型数组的元素,并返回表示结果构造类型的 Type 对象. 命名空间: System程序集: mscorlib(mscorlib.dll 中) public ...
- Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法
Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3 ...
- python 面向对象专题(六):元类type、反射、函数与类的区别、特殊的双下方法
目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3. 函数与类的区别 4. 特殊的双下方法 1. 元类type type:获取对象 ...
- java学习:用反射构造bean
先贴一些反射的基本知识:-------------------------------------------------------------------- 一.什么是反射:反射的概念是由Smit ...
- java 利用反射构造泛型类
1.构造BaseDao泛型类 class BaseDao<T>{ private Class<T> entityClass; // 通过反射获取实际运行的精确类 public ...
- Java反射获取泛型类型
本文链接:https://blog.csdn.net/hongxingxiaonan/article/details/49202613 在Java反射技术的应用中,取得一个类的成员.方法和构造函数相对 ...
- Java 反射 -- 获取泛型类型
先写一个类: public class Demo03 { public void test01(Map<String, User> map, List<User> list) ...
- python---issubclass/type/isinstance/ 反射(内置函数getattr/delattr...)
# 一 python面向对象-内置函数(issubclass(), type(), isinstance()) # issubclass 判断xxxx类是否是xxxx类的子类 class egg: p ...
- day17 isinstance type issubclass 反射
1. issubclass,type,isinstance 1.issubclass 判断xxx是否yyy的子类 例: class Foo: pass class Bar(Foo): pass cla ...
随机推荐
- element-ui和npm、webpack、vue-cli搭建Vue项目
一.element-ui的简单使用 1.安装 1. npm 安装 推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用. npm i element-ui -S 2. CDN ...
- virtualBox centos 6.5 硬盘扩容
1. 操作virtual Box 将该虚拟机关机,然后将打开管理->介质管理 调整硬盘大小 2. 操作Linux 1. 将放大的进行分区建立 2. 将分区建立分区表 3. 将该分区合并到root ...
- 51nod1812树的双直径(换根树DP)
传送门:http://www.51nod.com/Challenge/Problem.html#!#problemId=1812 题解:头一次写换根树DP. 求两条不相交的直径乘积最大,所以可以这样考 ...
- Harbo1.5.2离线搭建
环境说明 操作系统版本:Centos7.5 docker版本:docker-ce 17.03.2 harbor版本:v1.5.2 docker-compose: 1.22.0 基础环境搭建 系统优化 ...
- 2018-2019-2 实验一 Java开发环境的熟悉
实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用IDEA编辑.编译.运行.调试Java程序 实验知识点 1. JVM.JRE.JDK的安装位置与区别: 2. 命令行运行javac:ja ...
- 第十一节:Bundles压缩合并js和css及原理分析
一. 简介 1.背景:浏览器默认一次性请求的网络数是有上限的,如果你得js和css文件太多,就会导致浏览器需要多次加载,影响页面的加载速度, MVC中提供Bundles的方式压缩合并js和css,是M ...
- 常用的消息队列中间件mq对比
原文地址:https://blog.csdn.net/qq_30764991/article/details/80239076 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量 ...
- [物理学与PDEs]第5章第3节 守恒定律, 应力张量
5. 3 守恒定律, 应力张量 5. 3. 1 质量守恒定律 $$\bex \cfrac{\p \rho}{\p t}+\Div_y(\rho{\bf v})=0. \eex$$ 5. 3. 2 应 ...
- $m$ 整除 $10^k$ 的一个充分条件
若 (1) 既约分数 $\cfrac{n}{m}$ 满足 $0<\cfrac{n}{m}<1$; (2) 分数 $\cfrac{n}{m}$ 可以化为小数部分的一个循环节有 $k$ 位数字 ...
- Eclipse中的sysout与debug-遁地龙卷风
(-1)调试 在读<<一个程序员的奋斗史>>时里面提到这是一件很low的事情,突然想到自己也一直用sysout, 我是一个有情怀的人! (0)sysout的坏处 之所以长久的使 ...