C#反射机制
最近仔细学习了一下C#的反射机制,希望能和大家分享。提到反射我想大家都不陌生,反射
提供了封装程序集、模块和类型的对象(Type类型)。可以使用反射动态创建类型的实例,
将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性,所在命名
空间usingSystem.Reflection。
反射的作用:
1.使用反射可以动态创建类型的实例,然后将实例再邦定到现有的对象或从现有对象中获取类
型。
2.应用程序需要在运行时从某个特定的程序集中载入特定的类型,以创建特定类型的实例。
3.正是因为反射的特性(动态创建实例)所以在多个模块之间减少代码的紧偶合方面,利用
反射可以起到了很大的改善。但是反射也有它的弊端,就是要以牺牲性能为代价,而且有些信
息利用反射是无法得到的。在使用时要根据情况进行选择。我想通过下图的层次模型大家可能
会更明白它的机制。
以上关于反射知识了解之后,在通过代码大家可能会更好的理解反射:
首先在Vs2008中创建一个类型,命名为ReflectDemo类库。并添加一个名为ReflectTest
的类
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespaceSKY.ReflectDemo
{
publicclassReflectTest:IPerson
{
privatestring_name;
privateint_age;
publicstringName{get{returnthis._name;}set{this._name=
value;}}
publicintAge{get{returnthis._age;}set{this._age=value;}}
publicReflectTest(stringname,intage)
{
this._name=name;
this._age=age;
}
publicstringWelcomeInfo(stringname)
{
return"welcomecomehere"+name;
}
publicstaticstringWriteStaticInfo(stringname)
{
return"welcomecomeherestatic"+name;
}
publicstaticstringWriteStaticNoParam()
{
return"StaticandNoparma";
}
publicvoidShow(stringinfo)
{
Console.WriteLine(info);
}
publicReflectTest(){}
publicstringWriteNoPara()
{
return"你使用的是无参的方法";
}
privatestringWritePrivate()
{
return"私有类型的方法";
}
#regionIPerson成员
publicintAdd()
{
returnAge;
}
#endregion
}
publicinterfaceIPerson
{
///
///添加对象
///
///
intAdd();
}
}
然后再创建一个客户端程序:例如clientTestDemo,添加刚刚新建的程序集引用,引用命名
空间usingSystem.Reflection
classProgram
{
delegatestringTestDelegate(stringname);
staticvoidMain(string[]args)
{
//引导程序集//
//Assemblyass=Assembly.LoadFrom(("SKY.ReflectDemo.dll"));
//Assembly
ass=Assembly.GetAssembly(typeof(SKY.ReflectDemo.ReflectTest);
Assemblyass=Assembly.Load("SKY.ReflectDemo");//功能同上
Console.Write(ass.FullName+"\n");
//显示该dll下所有的类//
foreach(Typetypeinass.GetTypes())
{
Console.Write(type.Name+"\n");
}
//显示该dll下指定类//
Typeitype=ass.GetType("SKY.ReflectDemo.ReflectTest");
Console.Write(itype.Name);
Typeitype1=typeof(SKY.ReflectDemo.ReflectTest);
//所有模块//
foreach(Moduletempinass.GetModules())
{
Console.WriteLine(temp.Assembly.FullName);
}
//创建该类的实例,后面的param为有参构造函数的参
数//
object[]param={"test",30};//构造函数参数
SKY.ReflectDemo.ReflectTesttemp1=
(SKY.ReflectDemo.ReflectTest)Activator.CreateInstance(itype1,param);
//SKY.ReflectDemo.ReflectTesttemp1=
(SKY.ReflectDemo.ReflectTest)ass.CreateInstance("SKY.ReflectDemo.ReflectTest
");
Console.WriteLine(temp1.WriteNoPara());
//显示所有的共有方法
//
MethodInfo[]methods=itype.GetMethods();
Console.WriteLine("------------------------显示所有的共有方法---------------
----------");
foreach(MethodInfotempinmethods)
{
Console.WriteLine(temp.Name);
}
//显示特定方法
//
Console.WriteLine("------------------------显示特定方法----------------------
--------");
MethodInfomethod1=itype.GetMethod("WriteStaticInfo");//带参的静态
方法
Console.WriteLine(method1.Name);
object[]param1={"使用的是静态方法"};
strings1=(string)method1.Invoke(null,param1);
Console.WriteLine("执行后:"+s1+"\n");
MethodInfomethod2=itype.GetMethod("WriteStaticNoParam");//无参静
态方法
Console.WriteLine(method2.Name);
strings2=method2.Invoke(null,null)asstring;
Console.WriteLine("执行后:"+s2+"\n");
MethodInfomethod3=itype.GetMethod("WelcomeInfo");//带参的非静态
方法
Console.WriteLine(method3.Name);
object[]param2={"使用的是带有参数的非静态方法"};
strings3=(string)method3.Invoke(temp1,param2);
Console.WriteLine("执行后:"+s3+"\n");
MethodInfomethod4=itype.GetMethod("WriteNoPara");//无参非静态方法
Console.WriteLine(method4.Name);
strings4=method4.Invoke(temp1,null)asstring;
Console.WriteLine("执行后:"+s4+"\n");
MethodInfomethod5=itype.GetMethod("WritePrivate",
BindingFlags.NonPublic|BindingFlags.Instance);//无参私有非静态方法
Console.WriteLine(method5.Name);
strings5=method5.Invoke(temp1,null)asstring;
Console.WriteLine("执行后:"+s5+"\n");
MethodInfomethod6=itype.GetMethod("Show");//返回类型为void的方法
Console.WriteLine(method6.Name);
object[]param3={"returnTypeisvoid"};
strings6=method6.Invoke(temp1,param3)asstring;
Console.WriteLine(s6);
//显示所有属性
88//
Console.WriteLine("------------------------显示所有属性----------------------
--------");
PropertyInfo[]pros=itype.GetProperties(BindingFlags.Public|
BindingFlags.NonPublic|BindingFlags.Instance);
foreach(PropertyInfotempinpros)
{
Console.WriteLine(temp.Name);
}
//显示特定属性
88//
Console.WriteLine("------------------------显示特定属性----------------------
--------");
PropertyInfoproName=itype.GetProperty("Name");
proName.SetValue(temp1,"testName",null);
Console.WriteLine(proName.GetValue(temp1,null));
//显示构造函数
88//
Console.WriteLine("------------------------显示构造函数----------------------
--------");
ConstructorInfo[]cons=itype.GetConstructors();
foreach(ConstructorInfotincons)
{
Console.WriteLine(t.ToString());
}
//显示特定构造函数形式
88//
Console.WriteLine("------------------------显示特定构造函数形式-------------
-----------------");
ConstructorInfocon1=itype.GetConstructor(newType[]{typeof(string),
typeof(int)});
Console.WriteLine(con1);
ConstructorInfocon2=itype.GetConstructor(newType[]{});
Console.WriteLine(con2);
//委托的使用
//
Console.WriteLine("------------------------委托的使用------------------------
------");
TestDelegatetd=
(TestDelegate)Delegate.CreateDelegate(typeof(TestDelegate),temp1,
"WelcomeInfo");//非静态方法
Console.WriteLine(td("使用的是带有参数的非静态方法"));
TestDelegatetd2=Delegate.CreateDelegate(typeof(TestDelegate),
method1)asTestDelegate;//静态方法
Console.WriteLine(td2("使用静态方法"));
//TestDelegatetd1=new
TestDelegate(SKY.ReflectDemo.ReflectTest.WriteStaticInfo);
//Console.WriteLine(td1("使用的是带有参数的非静态方法222"));同上
运行结果如下:
有什么不对,请大家批评指确。
|
|