关于C#基础知识回顾--反射(三)
2023-06-13 09:15:03 时间
但是,如果对象是在运行时动态创建的,反射的功能就显示出来了。在这种情况下,需要首先获取一个构造函数列表,然后再调用列表中的某个构造函数,创建一个该类型的实例。通过这种机制,可以在运行时实例化任意类型的对象而不必在声明中指定。
为了获得某个类型的构造函数,需要调用Type对象上的GetConstructors()。常用形式为:
该方法返回一个描述构造函数的ConstructorInfo对象数组。ConstructorInfo中常用的
是GetParamters()方法,该方法返回给定构造函数的参数列表。
一旦找到了合适的构造函数,就调用ConstructorInfo定义的Invoke()方法来创建对象:
需要传递给此方法的所有参数都在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上的方法。