二、什么是反射、反射可以做些什么
什么是反射,反射能干嘛?反射是:
我们平时用反射主要做:
获取类型的相关信息反射的核心Type类,Type对象提供的属性和方法可以获取对象的一切信息,如:方法、字段、属性、事件...等等。 我们获取已加载程序集中类型的Type对象的几种方法:
不管使用那种,我们最终得到的结果都是一样的。 那么我们通过Type又能得到些什么信息呢? 获取类型本身信息() T1 = + + + + +
获取类型成员信息Type T1 = Mets = T1.GetMembers();
( m + m.MemberType.ToString()+ +
}
MemberType所能包含的成员类型有哪些呢?如: 注意:其中MemberInfo的属性DeclaringType返回的是这个属性定义的类型,而ReflectedType返回的是获取这个属性的对象类型。 如: Type T2 = Mets = ( m (m.Name== + m.MemberType.ToString() + +
T2中的Equals,我们知道这个方式是在Objec中定义的,在TClass中调用的,所以: 我们发现获取Type对象的成员大多都是以 isxxx、Getxxx、Getxxxs格式的。 isxxx格式的基本上都是判断是否是某类型。 Getxxx和Getxxxs都是放回某类型和某类型集合。其中主要的类型有: 它们都在??命名空间下,其每个isxxx、Getxxx、Getxxxs的细节实例用法就不一一演示了。和上面的GetMembers用法区别不大。 动态调用方法首先定义个类: fun( +
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> fun3()
{
Console.WriteLine(</span><span style="color: #800000;">"</span><span style="color: #800000;">我是fun3静态方法,我被调用了</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}
} 调用方式一调用带参实例方法fun Type T1 = ,BindingFlags.InvokeMethod,, TClass(), [] { });
调用无参实例方法fun2 Type T1 = ,);
调用静态方法 Type T1 = ,T1,);
我们发现了一个问题当我们调用实例方法的时候需要传实例对象过去。() 我们来说下这几个参数的意思吧。 第一个:要被动态调用的方法名。 第二个:是一个枚举,表示是调用一个方法 第三个:是Binder,传的是null,使用默认值。 第四个:传如实例对象()或者Type对象()。 第五个:要传给被调用发的参数数组。 调用方式二Type T1 = ,BindingFlags.Instance | BindingFlags.Public).Invoke( TClass(), [] { ,,BindingFlags.Static | BindingFlags.Public).Invoke(T1,);
? 使用其实和上面的方式一区别不大。 真正的全动态调用上面的两种方式,在编写代码的时候总是要先确定了已知的对象名和方法名。那么我们在不知道对象和方法名的时候是否也可以调用呢?答案是肯定的,实现如下: Console.WriteLine( className =<span style="color: #0000ff;">string funName =<span style="color: #000000;"> Console.ReadLine();
Type T1 =<span style="color: #000000;"> Type.GetType(className); ConstructorInfo ci = T1.GetConstructors()[<span style="color: #800080;">0]; <span style="color: #008000;">//<span style="color: #008000;">获取构造函数<span style="color: #0000ff;">var obj = ci.Invoke(<span style="color: #0000ff;">null);<span style="color: #008000;">//<span style="color: #008000;">实例化构造函数 <span style="color: #000000;"> T1.InvokeMember(funName,<span style="color: #0000ff;">null,obj,<span style="color: #0000ff;">null); 当然,这个代码只能只是fun2,因为上面的传参写死了。()? 效果如下:() 动态构造对象我们先定义一个对象: TClass( +
动态构造对象
Assembly asm == (TClass)asm.CreateInstance(,);<span style="color: #008000;">//<span style="color: #008000;">动态构造对象,方式二
ObjectHandle handler = Activator.CreateInstance(<span style="color: #0000ff;">null,<span style="color: #800000;">"<span style="color: #800000;"> net.TClass<span style="color: #800000;">");<span style="color: #008000;">//<span style="color: #008000;">null:当前程序集 obj =<span style="color: #000000;"> (TClass)handler.Unwrap(); <span style="color: #008000;">//<span style="color: #008000;">动态构造对象,方式三(构造有参构造函数) 执行效果图: 获取和修改属性 obj = = =
Name = type.InvokeMember(,BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, [] { })
type.InvokeMember(,BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance, [] {
PropertyInfo[] pros = type.GetProperties(---);//
从程序集中获得类型取得当前代码所在程序集Assembly ass = Assembly.GetExecutingAssembly();
Console.WriteLine("当前所在程序集名:"+ass.ManifestModule.Name);
Console.WriteLine("当前所在程序集路径:"+ass.Location);
? 通过反射加载程序集并创建程序中的类型对象从程序集中获得类型,这个应该是我们平时用得比较多。如我们所谓的依赖注入和控制反转就用到了通过反射从程序集中获取类型。 首先我们还是看看怎么从程序集中获得类型吧。我们可以使用Assembly类型提供的静态方法LoadFrom()或Load(),如: Assembly asm = Assembly.LoadFrom(= Assembly.Load();
区别: Assembly asm = Assembly.LoadFrom();
Assembly asm1 = Assembly.LoadFrom( |