zoukankan      html  css  js  c++  java
  • 程序集加载与反射(一):理论篇

    目录

    • 程序集加载
    • 获取类型信息
    • 构造类型实例
    • 通过反射发现成员
    • 调用成员

    一、程序集加载

    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方法可以,访问任何成员。但是如果多次调用,我们就需要多次进行绑定并调用,比较损耗性能。我们可以使用:

     

      

  • 相关阅读:
    ASP.NET MVC构建RESTful服务时返回Unauthorized(401)状态
    [原]jQuery Tab插件,用于在Tab中显示iframe,附源码和详细说明
    [转]线程间操作无效: 从不是创建控件“ *** ”的线程访问它。
    ASP.NET MVC中RESTful原教旨主义者的两个实现细节
    [原]C#绘制等值线二 等值线追踪
    Nginx+iptables 防DDOS,恶意访问,采集器
    Nginx+iptables屏蔽访问Web页面过于频繁的IP(防DDOS,恶意访问,采集器)
    解决CC攻击,Linux VPS,登录SSH,登录进VPS控制面板
    Inno Setup打包程序默认选择创建桌面图标
    苹果笔记本连接黑莓设置
  • 原文地址:https://www.cnblogs.com/sunchong/p/4550476.html
Copyright © 2011-2022 走看看