您的位置:首页 > 其它

利用反射动态创建对象

2012-03-24 10:13 330 查看
我们新建一个Console控制台项目,叫做Reflection4(因为本文是Part4,你也可以起别的名字)。然后,添加一个示范类,本文中将通过对这个示范类的操作来进行说明:

public class Calculator {

private int x;
private int y;

public Calculator(){
x = 0;
y = 0;
}

public Calculator(int x, int y) {
this.x = x;
this.y = y;
}
}



1.使用无参数构造函数创建对象

上面这个类非常简单,它包含两个构造函数,一个是有参数的构造函数,一个是无参数的构造函数,我们先看看通过反射,使用无参数的构造函数创建对象。创建对象通常有两种方式,一种是使用Assembly的CreateInstance方法:

Assembly asm = Assembly.GetExecutingAssembly();

Object obj = asm.CreateInstance("Reflection4.Calculator", true);

// 输出:Calculator() invoked

CreateInstance的第一个参数代表了要创建的类型实例的字符串名称,第二个参数说明是不是大小写无关(Ignore Case)。注意到CreateInstance返回的是一个Object对象,意味着如果想使用这个对象,需要进行一次类型转换。

创建对象的另一种方式是调用Activator类的静态方法CreateInstance:

ObjectHandle handler = Activator.CreateInstance(null, "Reflection4.Calculator");

Object obj = handler.Unwrap();

其中CreateInstance的第一个参数说明是程序集的名称,为null时表示当前程序集;第二个参数说明要创建的类型名称。Activator.CreateInstance返回的是一个ObjectHandle对象,必须进行一次Unwrap()才能返回Object类型,进而可以强制转换成我们需要的类型(本例中是Calculator)。ObjectHandle包含在System.Runtime.Remoting命名空间中,可见它是Remoting相关的,对于Remoting我暂时没有做太多研究,我们现在只要知道可以通过这种方式创建对象就可以了。


2.使用有参数构造函数创建对象

如果我们想通过有参数的构造函数创建对象,我们可以使用Assembly的CreateInstanc()的重载方法:

// 有参数构造函数创建对象

Assembly asm = Assembly.GetExecutingAssembly();

Object[] parameters = new Object[2]; // 定义构造函数需要的参数

parameters[0] = 3;

parameters[1] = 5;

Object obj = asm.CreateInstance("Reflection4.Calculator", true, BindingFlags.Default, null, parameters, null, null);

// 输出:Calculator(int x, int y) invoked

我们看一下CreateInstance需要提供的参数:

前两个在前一小节已经说明过了;
BindingFlags在前面我们也用到过,它用于限定对类型成员的搜索。在这里指定Default,意思是不使用BingdingFlags的策略(你可以把它理解成null,但是BindingFlags是值类型,所以不可能为null,必须有一个默认值,而这个Default就是它的默认值);
接下来的参数是Binder,它封装了CreateInstance绑定对象(Calculator)的规则,我们几乎永远都会传递null进去,实际上使用的是预定义的DefaultBinder;
接下来是一个Object[]数组类型,它包含我们传递进去的参数,有参数的构造函数将会使用这些参数;
接下来的参数是一个CultureInfo类型,它包含了关于语言和文化的信息(简单点理解就是什么时候ToString("c")应该显示“¥”,什么时候应该显示“$”)。

贴一个实际使用的类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace HealCore.BasicData
{
public class BasicDictionaryFactory
{
private static Assembly m_CurrentAsm;
private static string m_CurrAsmName = "HealCore.BasicData.";
static BasicDictionaryFactory()
{
m_CurrentAsm = Assembly.GetExecutingAssembly();

}
public static IBasicDictionaryBLL CreateBasicDictionaryBLL(string tableName, params object[] parameters)
{
try
{
if (parameters == null)
{
return (IBasicDictionaryBLL)m_CurrentAsm.CreateInstance(string.Format("{0}{1}Bll", m_CurrAsmName, tableName), true);
}
else
{
return (IBasicDictionaryBLL)m_CurrentAsm.CreateInstance(string.Format("{0}{1}Bll", m_CurrAsmName, tableName), true, BindingFlags.Default, null, parameters, null, null);
}
}
catch
{
return null;
}
}

public static object CreateModel(string tableName)
{
object objReturn = null;
try
{
objReturn = m_CurrentAsm.CreateInstance(tableName, true);
}
catch
{

}
return objReturn;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: