利用反射动态创建对象

原创 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;
        }
    }
}


Java反射机制创建对象

package lxf; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang...
  • smartboy_01
  • smartboy_01
  • 2014年04月08日 18:48
  • 29847

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

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

利用Java反射机制和Javassist实现Java对象及其属性的动态创建生成

利用Java反射机制和Javassist实现Java对象及其属性的动态创建生成   在开发过程中经常会遇到java对象的属性特征不确定的情况,比如属性的名称,属性的类型,属性的取值等不确定的情况,...
  • u012160689
  • u012160689
  • 2013年11月11日 16:42
  • 9816

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

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

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

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

C++new动态创建对象简单易懂的实例

  • 2011年04月02日 10:24
  • 884B
  • 下载

从零开始学C++之模板(四):用模板实现单例模式、模板方式实现动态创建对象

分类: 从零开始学C++2013-07-21 17:18 37人阅读 评论(0) 收藏 举报 用模板实现单例模式模板方式实现动态创建对象 一、用模板实现单例模式 在前面的文章...
  • pi9nc
  • pi9nc
  • 2013年07月21日 18:01
  • 1166

手写Spring之IOC基于xml动态创建对象

手写Spring之IOC基于xml动态创建对象        Spring作为Java Web最为流行的框架之一,其功能之强大,封装细节之全面不用过多赘述。使用Spring的方式很简单,不需要关注细...
  • zc290329105
  • zc290329105
  • 2018年01月07日 23:05
  • 26

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

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

.Net——动态创建对象

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

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