zl程序教程

您现在的位置是:首页 >  后端

当前栏目

关于C#基础知识回顾--反射(三)

c#基础知识反射 关于 -- 回顾
2023-06-13 09:15:03 时间

但是,如果对象是在运行时动态创建的,反射的功能就显示出来了。在这种情况下,需要首先获取一个构造函数列表,然后再调用列表中的某个构造函数,创建一个该类型的实例。通过这种机制,可以在运行时实例化任意类型的对象而不必在声明中指定。

为了获得某个类型的构造函数,需要调用Type对象上的GetConstructors()。常用形式为:
ConstructorInfo[]GetConstructors()
该方法返回一个描述构造函数的ConstructorInfo对象数组。ConstructorInfo中常用的
是GetParamters()方法,该方法返回给定构造函数的参数列表。
一旦找到了合适的构造函数,就调用ConstructorInfo定义的Invoke()方法来创建对象:
objectInvoke(object[]args)

需要传递给此方法的所有参数都在args中指定。如果不需要参数,args必须为null。另外,
args必须包含与参数个数相同的元素,并且实参的类型必须与形参的类型兼容。Invoke()方法返回
的是指向新构造对象的引用。
例子:
测试对象类

复制代码代码如下:

classMyClass
{
   intx;
   inty;
   publicMyClass(inti)
   {
       Console.WriteLine("一个参数的构造函数:");
       x=y=i;
   }
   publicMyClass(inti,intj)
   {
       Console.WriteLine("两个参数构造函数:");
       x=i;
       y=j;
       Show();
   }
   publicintSum()
   {
       returnx+y;
   }
   publicboolIsBetween(inti)
   {
       if(x<i&&i<y)
           returntrue;
       else
           returnfalse;
   }
   publicvoidSet(inta,intb)
   {
       Console.Write("函数:Set(inta,intb)");
       x=a;
       y=b;
       Show();
   }
   publicvoidSet(doublea,doubleb)
   {
       Console.Write("函数:Set(doublea,doubleb)");
       x=(int)a;
       y=(int)b;
       Show();
   }
   publicvoidShow()
   {
       Console.WriteLine("x:{0},y:{1}",x,y);
   }
}

使用反射:
复制代码代码如下:

usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Reflection;
namespaceReflection
{
   classProgram
   {
       staticvoidMain(string[]args)
       {
           InvokeConsDemo();
           Console.ReadKey();
       }

       staticvoidInvokeConsDemo()
       {
           Typet=typeof(MyClass);
           intval;
           ConstructorInfo[]ci=t.GetConstructors();
           Console.WriteLine("类构造函数如下:");
           foreach(ConstructorInfocinci)
           {
               Console.Write(""+t.Name+"(");
               ParameterInfo[]pi=c.GetParameters();
               for(inti=0;i<pi.Length;i++)
               {
                   Console.Write(pi[i].ParameterType.Name+""+pi[i].Name);
                   if(i+1<pi.Length)Console.Write(",");
               }
               Console.WriteLine(")");
           }
           Console.WriteLine();
           intx;
           for(x=0;x<ci.Length;x++)
           {
               ParameterInfo[]pi=ci[x].GetParameters();
               if(pi.Length==2)break;
           }
           if(x==ci.Length)
           {
               Console.WriteLine("没有找到两个参数的构造函数");return;
           }
           else
           {
               object[]consargs=newobject[2];
               consargs[0]=10;
               consargs[1]=20;
               objectreflectOb=ci[x].Invoke(consargs);
               Console.WriteLine("用reflectOb调用方法");
               Console.WriteLine();
               MethodInfo[]mi=t.GetMethods();
               foreach(MethodInfominmi)
               {
                   ParameterInfo[]pi=m.GetParameters();
                   if(m.Name.CompareTo("Set")==0&&pi[0].ParameterType==typeof(int))
                   {
                       object[]args=newobject[2];
                       args[0]=12;
                       args[1]=7;
                       m.Invoke(reflectOb,args);
                   }
                   elseif(m.Name.CompareTo("Set")==0&&pi[0].ParameterType==typeof(double))
                   {
                       object[]args=newobject[2];
                       args[0]=1.25;
                       args[1]=7.5;
                       m.Invoke(reflectOb,args);
                   }
                   elseif(m.Name.CompareTo("Sum")==0)
                   {
                       val=(int)m.Invoke(reflectOb,null);
                       Console.WriteLine("Sumis{0}",val);
                   }
                   elseif(m.Name.CompareTo("IsBetween")==0)
                   {
                       object[]args=newobject[1];
                       args[0]=13;
                       if((bool)m.Invoke(reflectOb,args))
                       {
                           Console.WriteLine("13isbetweenxandy");
                       }
                   }
                   elseif(m.Name.CompareTo("Show")==0)
                   {
                       m.Invoke(reflectOb,null);
                   }
               }
           }
       }
   }
}

运行结果为:



本例中,找到了一个两个参数的构造函数,那么使用下面的语句实例化了一个该类型的对象:
objectreflectOb=ci[x].Invoke(consargs);
调用Invoke()方法后,reflectOb将引用一个MyClass类型的对象。此后,程序将执行
reflectOb上的方法。
注意:本例为了简单起见,假设了一个使用两个参数的构造函数,并且两个参数都为int类型。但在实际的应用程序中,必须检验每一个参数的类型。