关闭

利用反射动态创建对象

1096人阅读 评论(0) 收藏 举报

我们新建一个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需要提供的参数:

  1. 前两个在前一小节已经说明过了;
  2. BindingFlags在前面我们也用到过,它用于限定对类型成员的搜索。在这里指定Default,意思是不使用BingdingFlags的策略(你可以把它理解成null,但是BindingFlags是值类型,所以不可能为null,必须有一个默认值,而这个Default就是它的默认值);
  3. 接下来的参数是Binder,它封装了CreateInstance绑定对象(Calculator)的规则,我们几乎永远都会传递null进去,实际上使用的是预定义的DefaultBinder;
  4. 接下来是一个Object[]数组类型,它包含我们传递进去的参数,有参数的构造函数将会使用这些参数;
  5. 接下来的参数是一个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;
        }
    }
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:385122次
    • 积分:3314
    • 等级:
    • 排名:第10605名
    • 原创:89篇
    • 转载:4篇
    • 译文:0篇
    • 评论:28条
    最新评论