zoukankan      html  css  js  c++  java
  • 思考反射使用

    我看了些反射的资料 有些不懂 反射是动态获取程序集中的对象 属性 方法 然后去调用 但是如果有了程序集 为什么不直接调用 而是用发射去调用呢

    做二次开发支持,提供接口的情况下用反射。
    比如你要求对方实现某个方法,先LoadAssembly,然后GetTypes,每个类型中GetMethod找合适的名字,找到就调用,可以扩展现有系统。还有很多需要用的地方,比如使用某个类,想清除所有注册的事件,你就要反射。


    反射是事先不知道的情况下,动态调用的,比方说你定义了一个接口IUser,A用户定义了一个类clsUserA继承你的接口,B用户也定一个了一个类clsUserB,继承你的接口

    你在A、B定义类之前要实现代码,这时候还没有clsUserA和clsUserB等类,怎么办呢,只能用反射了,让AB把他们类做成dll,你动态记载这个dll,然后反射这个dll的类,利用你的接口来调用A、B定义类的实现方法。

    反射通常具有以下用途:

    使用 Assembly 定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。

    使用 Module 发现以下信息:包含模块的程序集以及模块中的类等。您还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。

    使用 ConstructorInfo 发现以下信息:构造函数的名称、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。使用 Type 的 GetConstructors 或 GetConstructor 方法来调用特定的构造函数。

    使用 MethodInfo 发现以下信息:方法的名称、返回类型、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。使用 Type 的 GetMethods 或 GetMethod 方法来调用特定的方法。

    使用 FieldInfo 发现以下信息:字段的名称、访问修饰符(如 public 或 private)和实现详细信息(如 static)等;并获取或设置字段值。

    使用 EventInfo 发现以下信息:事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等;并添加或移除事件处理程序。

    使用 PropertyInfo 发现以下信息:属性的名称、数据类型、声明类型、反射类型和只读或可写状态等;并获取或设置属性值。

    使用 ParameterInfo 发现以下信息:参数的名称、数据类型、参数是输入参数还是输出参数,以及参数在方法签名中的位置等。

    当您在一个应用程序域的仅反射上下文中工作时,请使用 CustomAttributeData 来了解有关自定义属性的信息。使用 CustomAttributeData,您不必创建属性的实例就可以检查它们。

    System.Reflection.Emit 命名空间的类提供了一种特殊形式的反射,使您能够在运行时生成类型。

    反射也可用于创建称作类型浏览器的应用程序,它使用户能够选择类型,然后查看有关选定类型的信息。

    反射还有其他一些用途。JScript 等语言编译器使用反射来构造符号表。System.Runtime.Serialization 命名空间中的类使用反射来访问数据并确定要持久保存的字段。System.Runtime.Remoting 命名空间中的类通过序列化来间接地使用反射。

    反射的效率比直接用效率低很多,所以能不用反射就不要用

    使用反射来调用类型或者触发方法,或者访问一个字段或者属性时clr 需 要做更多的工作:校验参数,检查权限等等,所以速度是非常慢的。所以尽量不要使用反射进行编程
    面向接口

    反射是一种典型的元模式设计

    反射不需要引用
    只要知道你的dll所在的位置,dll文件的名称,内部的方法名
    就可以GetMethod来获取方法 就可以直接拿来用

    和引用差不多,楼主的意思是,我既然可以引用进来直接使用,为什么还要用反射这种执行效率底下的方法是不是?

    引用执行效率是高,但是你dll文件很多呢?就像电视台:中央一套.dll,中央二套.dll.....上百个dll文件
    你都要添加一次?  
    当这个页面用到那份dll的概率比较小并且dll文件是动态的,这时候 你可以用变量存储dll文件的名称
    来动态反射,避免多余的添加引用,这样方便 也比较合理,万一浙江又多开了几个电视台,你也不用就改程序了
    反正是动态的 管他新建电视台还是删除电视台,我只反射传进来的dll文件名

    委托的实现 貌似 也用到了 反射
    委托:是函数指针.跟反射完全扯不上关系.
    一般说,JAVA中实现了Observerable接口的类可以作为事件的发布者,也就是Subject;实现了Observer接口的类可以作为事件的观察者,也就是Observer

    C#中随便拿个类来都可以当做事件的发布者,随便拿个类来就可以当做观察者,之所以会这样,我个人理解是因为C#中的委托中运用了 反射
    追其原因 委托基类 Delegate类中有个 Object类型对象 Target ,有个MethodInfo 类型的对象 Method

    C#中 观察者和 被观察者 绑定时 即 
    myEvent += obj.func; //myEvent是委托变量 obj是类对象 func是obj的方法, 其中obj可以为任何类对象(也就是说观察者可以为任何类对象)
    系统会为我们执行 Target=obj ; Method=obj.GetType().GetMethod("func"); 

    而到事件触发的时候 即我们调用 myEvent(参数); //激发事件的时候
    系统就会利用反射执行 Method.Invoke(Target,参数);//利用反射执行方法
    而我们知道 myEvent在哪个类对象中 该对象就可以是事件的发布者 所以说任何类都可以当做Subject

    基本上,首先我们从需求出发,创造一种效果。特别是内容可以重构而行为接口完全不变的那些东西,往往对用户有震撼力。

    反射的代码,有经验的程序员都会慢慢地考虑用编译器就可以进行语法分析的代码来代替。如果用接口、很简练地实现代码就可以实现这种效果,那么就应该把反射代码扔到其它所有尝试都失败了之后才执行的角落里去。例如我们可能写:

    if(obj is IA)
    {
        使用IA接口来处理属性和方法;
    }
    else if(obj is IB)
    {
        使用IB接口来处理属性和方法;
    }
    else if(obj is ClassA)
    {
        使用ClassA类型来处理属性和方法;
    }
    else
    {
        使用反射方式来处理属性和方法
    }
    
  • 相关阅读:
    spring cloud 搭建(服务)
    spring cloud 搭建(配置中心)
    spring cloud 搭建(注册中心)
    spring cloud 搭建
    skywalking 配置和使用(windows)
    jenkins 发布报错
    web 显示 pdf
    springmvc Cacheable 不设置key
    iRed邮箱使用情况
    关闭SSL服务[iRedMail]
  • 原文地址:https://www.cnblogs.com/goto/p/2716251.html
Copyright © 2011-2022 走看看