使用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 ...
随机推荐
- Civil 3D .NET二次开发第11章代码升级至2018版注意事项
原来涉及2017的,均需要改为2018 原来的21改为22 代码中AeccXUiLand.AeccApplication.11.0"改为AeccXUiLand.AeccApplication ...
- 使用bat脚本永久激活Windows系统(摘抄)
使用bat脚本永久激活Windows系统 每次重装完系统后,右下角会提示系统未激活,无法进行一些个性化设置. 在这里我自己写了一个bat脚本用于激活Windows系统.(仅供学习) 文件下载: 链 ...
- 皮尔逊相关系数(Pearson Correlation Coefficient, Pearson's r)
Pearson's r,称为皮尔逊相关系数(Pearson correlation coefficient),用来反映两个随机变量之间的线性相关程度. 用于总体(population)时记作ρ (rh ...
- 11.4 Flask session,闪现
session 加密后放在用户浏览器的 cookie 中 于django 的自带session 不同,flask 的 session 需要导入 from flask import session 添加 ...
- zsh fg: no job control in this shell.
图片的上面就是将一个应用按Ctrl+Z,把任务放到后台里面.没法fg将任务回到前台运行. 在.zshrc中添加set -m. 具体原因不明.我切换到root用户里,没有出现这个问题.将我的.zshrc ...
- macOS卸载应用不彻底
总觉得macOS卸载应用时直接移到废纸篓卸载不干净.配置文件根据Unix的习惯应该存放在用户目录下,还需要删除这些文件. ~/Library/Application Support/(应用程序名称) ...
- 首次使用Oracle SQL Developer 提示: enter the full pathname for java.exe
https://www.cnblogs.com/520future/p/7699095.html 首次使用Oracle SQL Developer 提示: enter the full pathnam ...
- 微信小程序之canvas 文字断行和省略号显示
文字的多行处理在dom元素中很好办.但是canvas中没有提供方法,只有通过截取指定字符串来达到目的. 那么下面就介绍我自己处理的办法: wxml: <canvas canvas-id='wor ...
- Web of science数据下载以数据处理
目标网站分析 我们要获取的就是这几个数值 程序实现 # -*- coding: utf-8 -*- """ @Datetime: 2019/2/28 @Author: Z ...
- Linux中的pipe(管道)与named pipe(FIFO 命名管道)
catalogue . pipe匿名管道 . named pipe(FIFO)有名管道 1. pipe匿名管道 管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,常 ...