利用反射动态创建对象

原创 2012年03月24日 10:13:14

我们新建一个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;
        }
    }
}


相关文章推荐

C#利用反射动态创建对象 带参数的构造函数和String类型

最近笔者有一个想法需要利用反射动态创建对象(如string,int,float,bool,以及自定义类等)来实现,一直感觉反射用不好,特别是当构造函数带参数的时候。 MSDN上给出的例子十分复杂,网...

C# 利用反射动态创建对象

C# 利用反射动态创建对象   在VS.Net中,有很多种方法动态调用对象的构造函数。一是通过Activator类的CreateInstance()方法。这个方法我们在Remoting中也用过。它实际...

C++实现反射(根据类名动态创建对象)

和网上大多数实现一样,本文也采用工厂方法来实现对象的动态创建,唯一不同的在于,本文的实现优化了类的注册,使用起来更为简单。废话不多说,直接上代码(这也没什么可说的,看代码更加直观)。 DynamicF...

Swift通过类名动态创建对象的方式

原文出处:Swift通过类名动态创建对象的方式前言最近一些朋友问到我在Swift中如何通过类字符串名称的方式创建类实例的问题,起初以为与Objective-C的差不多吧,事实上还是有很大的差别的。下面...

java 动态创建对象

原博地址:http://www.cnblogs.com/zhangnanblog/archive/2012/04/27/2473820.html 做项目的时候遇到一个问题,就是需要动...

动态创建对象实例

动态创建对象实例 对非可视的系统对象类型使用CREATE 语句创建对象实例实例生成后就可以使用点运算符. 引用对象的成员了CREATE 语句返回对象实例的句柄通过该句柄引用新生成的...

MFC中关于运行时类信息及动态创建对象的两个宏的意义

MFC运行时类信息 用途: 程序在运行时,获取对象类的信息及类的继承关系 实现: 1、定义的类必须继承自CObject类。 2、类内声明宏DECLARE_DYNAMIC(),类外实现宏IMPLE...
  • ligand
  • ligand
  • 2015年11月14日 21:56
  • 1341

Protobuf 动态创建对象

准备用netty+protobuf做一个通讯模块. 在netty官网找到一个LocalTime的一个demo, class LocalTimeServerPipelineFactory imp...
  • WQ560
  • WQ560
  • 2013年04月18日 08:47
  • 1514

.Net——动态创建对象

刚开始看到这个标题的时候其实我也是很难接受的,duang~因为实在想不出什么时候我要去这样子创建对象,干嘛不new一个呢?但根据学习设计模式的经验来说,有时候,不去new对象才是最灵活的做法。 首先,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用反射动态创建对象
举报原因:
原因补充:

(最多只允许输入30个字)