标签:
目录
一、程序集加载
Load方法:CLR通过调用System.Rreflection.Assemblly类的静态方法来显示加载程序集。
public static Assembly Load(AssemblyName assemblyRef);
public static Assembly Load(string assemblyString);
LoadFrom方法:同样我们可以使用 远程加载程序集。此方法首先打开程序集,并通过 public static AssemblyName GetAssemblyName(string assemblyFile);方法提取到程序集名称,然后再会使用Load方法加载程序集。
public static Assembly LoadFrom(string path);
ReflectionOnlyLoad方法:加载程序集,只是获取程序集的相关信息。但CLR禁止此程序集中的代码执行。
public static Assembly ReflectionOnlyLoad(string assemblyString);
同样也有ReflectionOnlyLoadFrom
public static Assembly ReflectionOnlyLoadFrom(string path);
二、获取类型信息
1、System.Type.GetType方法
public static Type GetType(string typeName);
字符串必须执行的是全名,对于基元类型不能识别,识别CLR类型。
2、System.Type.ReflectionOnlyGetType
public static Type ReflectionOnlyGetType(string typeName, bool throwIfNotFound, bool ignoreCase);
只是显示反射上下文内容,不能够执行代码。
3、操作符typeof(),可以对类型进行晚期绑定并与早期绑定类型进行比对。
static Encryption(object o) { //早期绑定:o.GetTye() //晚期绑定typeof if (o.GetType() == typeof(Encryption)) { } }
三、构造类型实例
1、System.Activator.CreateInstance
public static object CreateInstance(Type type);
public static ObjectHandle CreateInstance(string assemblyName, string typeName);
上面的方法返回值有的是ObjectHandle类型,此类型允许将一个AppDomian中的对象传送到另一个AppDomian而且不需要具体化哪个对象。如果需要具体化具体的类型就可以调用 Unwrap()方法。
2、System.Activator.CreateComInstanceFrom
public static ObjectHandle CreateComInstanceFrom(string assemblyName, string typeName);
程序集和类型都是字符串直接指定,不过,程序集需要使用LoadFrom方法来加载得到程序集,并且提取名称作为参数传递。当然对于返回值我们也需要调用Unwrap()进行具体化。
System.Reflection.Assembly assy= System.Reflection.Assembly.LoadFrom(""); System.Activator.CreateComInstanceFrom(assy.FullName, "Encryption");
四、通过反射发现成员
层次结构
因为Reflection.MemberInfo是成员结构层次的根,所以需要了解一下MemberInfo的成员组成:
1、执行以下代码,区分一下DeclaringType和ReflectedType:
DeclaringType:声明方法的类;ReflectedType:当前的反射类
public class UnitTest1 { [TestMethod] public void TestMethod1() { System.Reflection.MemberInfo[] mi = typeof(MyType).GetMembers(); foreach (var m in mi) { var dt= m.DeclaringType; var rt = m.ReflectedType; } } } public sealed class MyType { public override string ToString() { return null; } }
ToSting()方法,因为声明它的类和当前所在的反射类是同一个即MyType。
Equal()方法,因为声明它的类是Object,但是当前反射类是MyType。
以上就是DeclaringType和ReflectedType的区别。
2、BindingFlags:筛选返回的成员种类
我们可以调用Type的 GetMethod、GetProperty、GetNestedType各种Get。我们可以组合BindingFlags,来筛选我们需要的东西。
五、调用成员的类型
我们可以找出我们需要的东东,然后我们可以进行调用。调用属性、方法、构造函数等等。
调用FieldInfo,可以获取或者设置字段的值;
调用ConstructorInfo,可以向构造传递实参,从而构造类型的一个实例;
调用MethodInfo,可以通过传递实参来调用方法,并返回它的返回值;
调用PropertyInfo,可以调用属性的get和set访问其方法。
1、调用方法
public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, CultureInfo culture);
调用此方法可以在成员类型里搜索一个匹配的类型成员,如果没找到,抛出异常。如果找到,就会调用此成员。我们可以归纳以上行为为两个阶段:绑定和调用。
我们调用一个绑定器方法时,首先我们传递 目标成员 name、方法的所有参数类型 args 、指定的 BindingFlags invokeAttr 。
参数 name :目标成员。名字
参数 invokeAttr :这些位标识的组合可以帮助我们更好的定位我们的成员 IgnoreCase = 1, DeclaredOnly = 2,Instance = 4,Static = 8,Public = 16等
参数 binder :它的类型从System.Relflection.Binder 抽象类型派生的,从Binder派生的类型,封装了InverMember方法确定绑定类型的规则。编译器为我们定义了System.DefaultBinder 的实际类型可以为我们使用。可以帮助我们自动的类型转换。
参数 target : 目标成员所在类的实例的一个引用。静态类 =null。
参数 args: 传递的参数。
参数 culture: 如果有自己的绑定器可以使用此参数,如果前面参数使用了System.DefaultBinder,culture参数就可以省略了。
2、一次绑定,多次调用
我们利用Type的InvokeMember方法可以,访问任何成员。但是如果多次调用,我们就需要多次进行绑定并调用,比较损耗性能。我们可以使用:
标签:
原文地址:http://www.cnblogs.com/sunchong/p/4550476.html