博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用反射动态创建类型实例
阅读量:6637 次
发布时间:2019-06-25

本文共 3462 字,大约阅读时间需要 11 分钟。

.NET中除了构造函数外,还有多种方式可以创建类型的实例。下面总结了几种常见的通过反射创建类型实例的方法。

假设我们需要创建有这样一个类型的实例:

public class Employee{    public String Name { get; set; }    public Employee(String name)    {        Name = name;    }    public Employee ()    {    }    public void Say(String greeting)    {        Console.WriteLine(String.Format("Employee {0} say: {1} ", Name, greeting));    }}

 

System.Activator

System.Activator类中提供了三组静态方法来创建类型的实例,每组方法均提供多个重载,适用不同的场景。个别重载方法返回ObjectHandle对象,需要unwrap后才能获取对象实例。

CreateInstance

CreateInstanceFrom

CreateComInstanceFrom

以下实例代码演示了如何使用上述方法创建对象实例:

// 使用无参构造函数var employee = (Employee)Activator.CreateInstance(typeof(Employee));employee = Activator.CreateInstance
();employee.Say("CreateInstance with default ctor");// 使用有参构造函数employee=(Employee)Activator.CreateInstance(typeof(Employee), new object[] { "David" });employee.Say("CreateInstance with ctor with args"); string assembly ="Test, Version=1.0.4562.31232, Culture=neutral, PublicKeyToken=null";string type="Test.Tests.Employee";var employeeHandle = Activator.CreateInstance( assembly, type);employee = (Employee)employeeHandle.Unwrap();employee.Say("CreateInstance and unwrap."); string assemblyPath=@"E:\StudyProj\ShartDev\Test\Test\bin\Debug\Test.exe";employeeHandle = Activator.CreateInstanceFrom( assemblyPath, type);employee = (Employee)employeeHandle.Unwrap();employee.Say("CreateInstanceFrom and unwrap.");

 

System.AppDomain

与Activator类似,AppDomain提供了4组实例方法创建类型的实例。除了创建对象外,还指定了对象所归属的AppDomain。

CreateInstance

CreateInstanceAndUnwrap

CreateInstanceFrom

CreateInstanceFromAndUnwrap

 

System.Type

使用Type.InvokerMember可以调用类型的方法、属性。自然也可以通过调用类型的构造函数来创建一个类型的实例。

 

//直接调用无参构造函数Object obj = typeof(Employee).InvokeMember(null, BindingFlags.CreateInstance, null, null, null);Employee employee =obj as Employee;employee.Say("InvokeMember default ctor");// 使用带参数的构造函数obj = typeof(Employee).InvokeMember(null, BindingFlags.CreateInstance, null, null, new object[] { "david" });employee = obj as Employee;((Employee)obj).Say("InvokeMember ctor with argument");

 

 

System.Reflection.ConstructorInfo

除了直接适用InvokerMember调用构造函数外,还可以先以反射的方式获取构造函数对应的MemberInfo,具体类型为ConstructorInfo,然后使用其Invoke方法。

// 首先获取构造函数,然后再InvokeConstructorInfo ctor = typeof(Employee).GetConstructor(new Type[] { typeof(string) });var emp = (Employee)ctor.Invoke(new object[]{
"david"});emp.Say("ConstructorInfo");

本来一步可以完成的操作,分两边走完的确是麻烦了些,但好处在于获取ConstructorInfo之后,后续多次调用Invoke时,避免重复绑定,可以提高效率,适用于需要重复多次使用同一个构造函数创建实例的场景。反射的绑定过程是按照字符串比较的方式在程序集元数据中查找匹配的成员,速度较慢。

 

数组,委托和泛型类型的创建

Array

Array类型可以使用静态方法Array.CreateInstance方法创建。Array类还提供了其他重载方法来创建多维数组。

var array = Array.CreateInstance(typeof(int),20);Console.WriteLine(array.GetType().Name+" " +array.Length);

委托

创建Delegate类型需要使用Delegate.CreateDelegate.

MethodInfo methodInfo = typeof(CreateInstanceTest).GetMethod("StaticDoSomething",BindingFlags.Public|BindingFlags.Static);Delegate dele = Delegate.CreateDelegate(typeof(DoSomethingDelegate),methodInfo);dele.DynamicInvoke("just say hi");

Generic

创建泛型类型的实例,首先要获取对应的开放类型(Open type)的引用,然后调用Type类型的MakeGenericType方法,传入一个包含泛型参数的数组即可获取一个封闭类型(Closed Type).使用该封闭类型,调用Activator接受Type参数的某个方法既可以构造出具体的实例。

 

Type open = typeof(Dictionary<,>);Type closeType = open.MakeGenericType(typeof(String),typeof(object));object obj = Activator.CreateInstance(closeType);Console.WriteLine(obj.GetType());

 

以上即是常用的几种创建对象实例的方式,实际应用中可以根据具体场景做选择。

 

出处:http://www.cnblogs.com/dytes/archive/2012/06/29/2569488.html

你可能感兴趣的文章
176. Second Highest Salary SQL查询语句中的 limit offset
查看>>
操作系统的内存对齐机制学习笔记
查看>>
web app 和移动端app(混合app---react native;vue+veex) 开发技术和区别
查看>>
Python高级正则
查看>>
mha配置参数详解
查看>>
mysql-备份数据库脚本
查看>>
[题解]POJ 3207 Ikki's Story IV - Panda's Trick
查看>>
高并发高可用的架构实践-剖析架构(三)
查看>>
CentOS6.2编译安装Nginx1.2.0
查看>>
Part 10.网络编程--网络通信过程
查看>>
java 不同list 添加元素
查看>>
正在调用的 ServicedComponent 配置不正确(请使用 regsvcs 重新注册)
查看>>
jquery基本
查看>>
Aspose.Cells 根据Excel模板导出数据统计
查看>>
FrameLsyout
查看>>
UML图概述
查看>>
我的暑假周记2018.8.19
查看>>
结对-及格成绩查询-开发过程
查看>>
配置COCO API(安装COCO)
查看>>
内存泄露
查看>>