反射机制(2)动态创建并调用对象

本文详细介绍了如何使用.NET Framework的Assembly和Activator类创建对象实例,包括无参构造函数与有参构造函数的使用方法,并展示了如何通过Type类的InvokeMember和MethodInfo类的Invoke方法调用对象的成员。同时,文章通过示例演示了遍历对象属性的技巧。本文旨在帮助开发者更好地理解和应用.NET反射API。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

示例通用对象:

namespace Test
{
    class User   //通用User类
    {
        private string name;

        public User()
        {
            name = "zhangsan";
        }

        public User(string value)
        {
            name = value;
        }

        public string getName()
        {
            return "this is " +name + "!";
        }

        public string showName(string father,string monther)
        { 
            return father +" and " + monther +"'s son is " + name ;
        }
    }
}

一、创建对象通常有2种方式:

 1、使用Assembly类的CreateInstance方法:

         CreateInstance方法有3个重载函数:

       (1)public Object CreateInstance (string typeName)   //从程序集中查找指定的typeName并创建它,查找typeName时区分大小写

                 typeName参数:表示要创建的类型实例的名称。

       (2)public Object CreateInstance (string typeName,bool ignoreCase)   // 从程序集中查找指定的typeName并创建它

                 ignoreCase参数:表示是否忽略大小写查找typeName,true = 忽略大小写,false = 区分大小写。

       (3)public Object CreateInstance (string typeName,bool ignoreCase,BindingFlags bindingAttr,Binder binder,Object[] args,CultureInfo culture,Object[]

                  activationAttributes)

                 bindingAttr参数:限定查找的类型。

                 binder参数:一个启用绑定、参数类型强制、成员调用以及通过反射进行 MemberInfo 对象检索的对象。如果binder 为null,则使用默认联编程序。

                 args参数:包含要传递给构造函数的参数。

                 culture参数:用于控制类型强制的 CultureInfo 的实例。例如将100强制转换成Double类型。null则使用当前线程的 CultureInfo。

                 activationAttributes参数:包含一个或多个可以参与激活的激活属性。

     示例:
         //无参构造函数创建对象
         Object obj =  Assembly.GetExecutingAssembly().CreateInstance("Test.User",true);  

         //有参构造函数创建对象
         Object[] paramters = new Object[1];
         paramters[0] = "lisi";
         //BindingFlags.Default表示不指定绑定标志。
         Object obj = Assembly.GetExecutingAssembly().CreateInstance("Test.User",true,BindingFlags.Default,null,paramters,null,null);
2、调用Activator类的静态方法CreateInstance:

        CreateInstance方法共有14个重载函数,这里只讲几个常用的:

      (1)public static Object CreateInstance (Type type)  

                 type参数:要创建的对象的类型。

      (2)public static Object CreateInstance (Type type,params Object[] args)

                args参数:包含要传递给构造函数的参数。

      (3)public static ObjectHandle CreateInstance (string assemblyName,string typeName)

               assemblyName参数:指定查找typeName的程序集的名称。null表示当前程序集。

               typeName参数:表示要创建的类型实例的名称。

               注意:参数返回的是ObjectHandle类型,必须进行一次Unwrap()才能返回Object类型。

      (4)public static ObjectHandle CreateInstance (string assemblyName,string typeName,bool ignoreCase,BindingFlags bindingAttr,Binder binder,Object[] args,CultureInfo culture,Object[] activationAttributes,Evidence securityInfo)

               参数说明同上Assembly类的CreateInstance方法的重载函数(3)。

               注意:参数返回的是ObjectHandle类型,必须进行一次Unwrap()才能返回Object类型。

      (5)public static Object CreateInstance (Type type,BindingFlags bindingAttr,Binder binder,Object[] args,CultureInfo culture,Object[] activationAttributes)

               参数说明同上。

        示例:
            //无参构造函数创建对象
            System.Runtime.Remoting.ObjectHandle oh = Activator.CreateInstance(null, "Test.User");
            Object obj = oh.Unwrap();

            //有参构造函数创建对象
            Object[] paramters = new Object[1];
            paramters[0] = "lisi";
            System.Runtime.Remoting.ObjectHandle oh = Activator.CreateInstance(null, "Test.User",false,BindingFlags.CreateInstance,null,paramters,null,null,null);
            Object obj = oh.Unwrap();

二、调用对象通常也有2种方式:

  1、使用Type类的InvokeMember方法:

         InvokeMember方法有3个重载函数:

       (1)public Object InvokeMember (string name,BindingFlags invokeAttr,Binder binder,Object target,Object[] args)

                 name参数:表示要调用的构造函数、方法、属性或字段成员的名称。

                 invokeAttr参数:限定查找的类型。如果是调用对象方法的话,通常为BindingFlags.InvokeMethod,调用对象属性时,为BindingFlags.GetProperty;而如果是创建对象的话,为BindingFlags.CreateInstance。

                 binder参数:一个启用绑定、参数类型强制、成员调用以及通过反射进行 MemberInfo 对象检索的对象。如果binder 为null,则使用默认联编程序。

                 target参数:表示要在其上调用指定成员的 Object。

                 args参数:包含传递给要调用的成员的参数的数组。 

       (2)public Object InvokeMember (string name,BindingFlags invokeAttr,Binder binder,Object target,Object[] args,CultureInfo culture)

                 culture参数:用于控制类型强制的 CultureInfo 的实例。例如将100强制转换成Double类型。null则使用当前线程的 CultureInfo。

       (3)public abstract Object InvokeMember (string name,BindingFlags invokeAttr, Binder binder,Object target,Object[] args,ParameterModifier[] modifiers,CultureInfo culture, string[] namedParameters)

                modifiers参数:ParameterModifier 对象数组,表示与 args 数组中的相应元素关联的属性 (Attribute)。

                namedParameters参数:包含参数名称的数组,args 数组中的值被传递给这些参数。

         备注:Type.InvokeMember方法不仅可以用于调用对象,也可可以用于创建对象。

    示例:      
           //无参创建对象
            Object obj =  Assembly.GetExecutingAssembly().CreateInstance("Test.User",true);
            Type myType = typeof(Test.User);

            //调用无参方法getName
            string result = (string)myType.InvokeMember("getName",BindingFlags.InvokeMethod,null,obj,null);
            Console.WriteLine(result);  //运行结果为This is zhangsan!
            
            Object[] paramters = new Object[2];
            paramters[0] = "sam";
            paramters[1] = "john";
            //调用有参方法showName并传递2个参数
            string result = (string)myType.InvokeMember("showName", BindingFlags.InvokeMethod, null, obj,paramters);
            Console.WriteLine(result);   //运行结果为sam and john's son is zhangsan

      示例://遍历Color类的所有颜色
            Type colorType = typeof(System.Drawing.Color);

            PropertyInfo[] pis = colorType.GetProperties(BindingFlags.Static | BindingFlags.Public);

            foreach (PropertyInfo pi in pis)
            {
                System.Drawing.Color c = (System.Drawing.Color)colorType.InvokeMember(pi.Name, BindingFlags.GetProperty, null, colorType, null);

                Console.WriteLine("{0} (R:{1},G:{2},B:{3})",c.Name,c.R, c.G, c.B );
            }
       运行结果:
            Transparent (R:255,G:255,B:255)
            AliceBlue (R:240,G:248,B:255)
            AntiqueWhite (R:250,G:235,B:215)
            Aqua (R:0,G:255,B:255)
            Aquamarine (R:127,G:255,B:212)
            Azure (R:240,G:255,B:255)
            Beige (R:245,G:245,B:220)
            Bisque (R:255,G:228,B:196)
            Black (R:0,G:0,B:0)
            BlanchedAlmond (R:255,G:235,B:205)
            ....
            ....

2、使用MethodInfo类的Invoke方法:

          Invoke方法有2个重载函数:

        (1)public Object Invoke ( Object obj,Object[] parameters)

                  obj参数:对其调用方法或构造函数的对象。如果方法是静态的,则忽略此参数。如果构造函数是静态的,则此参数必须为空引用。

                  parameters参数:调用的方法或构造函数的参数列表。

                  返回值:包含被调用方法的返回值,如果调用的是构造函数,则为空引用。

        (2)public abstract Object Invoke (Object obj,BindingFlags invokeAttr,Binder binder,Object[] parameters,CultureInfo culture)

                 参数说明同上Assembly类的CreateInstance方法的重载函数(3)。

     示例:
            //创建对象
            Object obj = Assembly.GetExecutingAssembly().CreateInstance("Test.User", true);
            Type myType = typeof(Test.User);
            MethodInfo mi = myType.GetMethod("getName");
            //调用无参方法
            string result = (string)mi.Invoke(obj,null);
            Console.WriteLine(result);  //运行结果为This is zhangsan!
          
            MethodInfo mi = myType.GetMethod("showName");
            Object[] paramters = new Object[2];
            paramters[0] = "sam";
            paramters[1] = "john";
            //调用有参方法
            string result = (string)mi.Invoke(obj,paramters);
            Console.WriteLine(result); //运行结果为sam and john's son is zhangsan     
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜之子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值