C#反射Assembly 具体说明

1、对C#反射机制的理解
2、概念理解后,必须找到方法去完毕,给出管理的主要语法
3、终于给出有用的样例,反射出来dll中的方法

反射是一个程序集发现及执行的过程,通过反射能够得到*.exe或*.dll等程序集内部的信息。使用反射能够看到一个程序集内部的接口、类、方法、字段、属性、特性等等信息。在System.Reflection命名空间内包括多个反射经常使用的类,以下表格列出了经常使用的几个类。
类型 作用
Assembly 通过此类能够载入操纵一个程序集,并获取程序集内部信息
EventInfo 该类保存给定的事件信息
FieldInfo 该类保存给定的字段信息
MethodInfo 该类保存给定的方法信息
MemberInfo 该类是一个基类,它定义了EventInfo、FieldInfo、MethodInfo、PropertyInfo的多个公用行为
Module 该类能够使你能訪问多个程序集中的给定模块
ParameterInfo 该类保存给定的參数信息      
PropertyInfo 该类保存给定的属性信息

一、System.Reflection.Assembly类
     通过Assembly能够动态载入程序集,并查看程序集的内部信息,当中最经常使用的就是Load()这种方法。
     Assembly assembly=Assembly.Load("MyAssembly");
     利用Assembly的object CreateInstance(string) 方法能够反射创建一个对象,參数0为类名。
二、System.Type类
     Type是最经常使用到的类,通过Type能够得到一个类的内部信息,也能够通过它反射创建一个对象。一般有三个经常使用的方法可得到Type对象。
利用typeof() 得到Type对象
Type type=typeof(Example);
利用System.Object.GetType() 得到Type对象
Example example=new Example();
Type type=example.GetType();
利用System.Type.GetType() 得到Type对象
Type type=Type.GetType("MyAssembly.Example",false,true);
注意參数0是类名,參数1表示若找不到相应类时是否抛出异常,參数1表示类名是否区分大写和小写
   样例:
   我们最常见的是利用反射与Activator结合来创建对象。
   Assembly assembly= Assembly.Load("MyAssembly");
   Type type=assembly.GetType("Example");
   object obj=Activator.CreateInstance(type);
三、反射方法
    1.通过 System.Reflection.MethodInfo能查找到类里面的方法

Type type=typeof(Example);MethodInfo[] listMethodInfo=type.GetMethods();foreach(MethodInfo methodInfo in listMethodInfo)Cosole.WriteLine("Method name is "+methodInfo.Name);


2.我们也能通过反射方法运行类里面的方法2.我们也能通过反射方法运行类里面的方法

Assembly assembly= Assembly.Load("MyAssembly");Type type=assembly.GetType("Example");object obj=Activator.CreateInstance(type);MethodInfo methodInfo=type.GetMethod("Hello World");  //依据方法名获取MethodInfo对象methodInfo.Invoke(obj,null);  //參数1类型为object[],代表Hello World方法的相应參数,输入值为null代表没有參数


四、反射属性
   1.通过 System.Reflection.PropertyInfo 能查找到类里面的属性
     经常使用的方法有GetValue(object,object[]) 获取属性值和 SetValue(object,object,object[]) 设置属性值
四、反射属性
   1.通过 System.Reflection.PropertyInfo 能查找到类里面的属性
     经常使用的方法有GetValue(object,object[]) 获取属性值和 SetValue(object,object,object[]) 设置属性值
四、反射属性
   1.通过 System.Reflection.PropertyInfo 能查找到类里面的属性
     经常使用的方法有GetValue(object,object[]) 获取属性值和 SetValue(object,object,object[]) 设置属性值

Type type=typeof(Example);PropertyInfo[] listPropertyInfo=type.GetProperties();foreach(PropertyInfo propertyInfo in listPropertyInfo)Cosole.WriteLine("Property name is "+ propertyInfo.Name);


2.我们也能够通过下面方法设置或者获取一个对象的属性值2.我们也能够通过下面方法设置或者获取一个对象的属性值

 Assembly assembly=Assembly.Load("MyAssembly");Type type=assembly.GetType("Example");object obj=Activator.CreateInstance(type);PropertyInfo propertyInfo=obj.GetProperty("Name");    //获取Name属性对象var name=propertyInfo.GetValue(obj,null);                //获取Name属性的值PropertyInfo propertyInfo2=obj.GetProperty("Age");     //获取Age属性对象propertyInfo.SetValue(obj,34,null);                              //把Age属性设置为34


五、反射字段
    通过 System.Reflection.FieldInfo 能查找到类里面的字段
    它包含有两个经常用法SetValue(object ,object )和GetValue(object)  由于用法与反射属性很相似,在此不再多作介绍
   (略)
六、反射特性
   通过System.Reflection.MemberInfo的GetCustomAttributes(Type,bool)就可反射出一个类里面的特性,下面样例能够反射出一个类的全部特性
五、反射字段
    通过 System.Reflection.FieldInfo 能查找到类里面的字段
    它包含有两个经常用法SetValue(object ,object )和GetValue(object)  由于用法与反射属性很相似,在此不再多作介绍
   (略)
六、反射特性
   通过System.Reflection.MemberInfo的GetCustomAttributes(Type,bool)就可反射出一个类里面的特性,下面样例能够反射出一个类的全部特性

Type type=typeof("Example");object[] typeAttributes=type.GetCustomAttributes(false);       //获取Example类的特性foreach(object attribute in typeAttributes)Console.WriteLine("Attributes description is "+attribute.ToString());


通过以下样例,能够获取Example类Name属性的全部特性通过以下样例,能够获取Example类Name属性的全部特性

public class Example{[DataMemberAttribute]publics string Name{get;set;}..................}Type type = typeof(Example);        PropertyInfo propertyInfo=type.GetProperty("Name");    //获取Example类的Name属性foreach (object attribute in propertyInfo.GetCustomAttributes(false))        //遍历Name属性的全部特性Console.WriteLine(“Property attribute: "+attribute.ToString());

总结:

Assembly.Load()方法,Assembly.LoadFrom()方法,Assembly.LoadFile()方法的差别
在C#中,我们要使用反射,首先要搞清楚下面命名空间中几个类的关系:
    System.Reflection命名空间
    (1)   AppDomain:应用程序域,能够将其理解为一组程序集的逻辑容器
    (2)   Assembly:程序集类
    (3)   Module:模块类
    (4)   Type:使用反射得到类型信息的最核心的类
    他们之间是一种从属关系,也就是说,一个AppDomain能够包括N个Assembly,一个Assembly能够包括N个Module,而一个Module能够包括N个Type.

    1,Assembly.Load()
    这种方法通过程序集的长名称(包含程序集名,版本号信息,语言文化,公钥标记)来载入程序集的,会载入此程序集引用的其它程序集,普通情况下都应该优先使用 这种方法,他的运行效率比LoadFrom要高非常多,并且不会造成反复载入的问题(原因在第2点上说明)
    使用这种方法的时候, CLR会应用一定的策略来查找程序集,实际上CLR按例如以下的顺序来定位程序集:
    ⑴假设程序集有强名称,在首先在全局程序集缓(GAC)中查找程序集。
    ⑵假设程序集的强名称没有正确指定或GAC中找不到,那么通过配置文件里的<codebase>元素指定的URL来查找
    ⑶假设没有指定强名称或是在GAC中找不到,CLR会探測特定的目录:
    如果你的应用程序文件夹是C:\AppDir,<probing>元素中的privatePath指定了一个路径Path1,你要定位的程序集是AssemblyName.dll则CLR将依照例如以下顺序定位程序集
    C:\AppDir\AssemblyName.dll
    C:\AppDir\AssemblyName\AssemblyName.dll
    C:\AppDir\Path1\AssemblyName.dll
    C:\AppDir\Path1\AssemblyName\AssemblyName.dll
    假设以上方法不能找到程序集,会发生编译错误,假设是动态载入程序集,会在执行时抛出异常!
    2,Assembly.LoadFrom()
    这种方法从指定的路径来载入程序集,实际上这种方法被调用的时候,CLR会打开这个文件,获取当中的程序集版本号,语言文化,公钥标记等信息,把他们传递给 Load方法,接着,Load方法採用上面的策略来查找程序集。假设找到了程序集,会和LoadFrom方法中指定的路径做比較,假设路径同样,该程序集 会被觉得是应用程序的一部分,假设路径不同或Load方法没有找到程序集,那该程序集仅仅是被作为一个"数据文件"来载入,不会被觉得是应用程序的一部分。 这就是在第1点中提到的Load方法比LoadFrom方法的运行效率高的原因。另外,因为可能把程序集作为"数据文件"来载入,所以使用 LoadFrom从不同路径载入同样程序集的时候会导致反复载入。当然这种方法会载入此程序集引用的其它程序集。
    3,Assembly.LoadFile()
    这种方法是从指定的文件来载入程序集,和上面方法的不同之处是这种方法不会载入此程序集引用的其它程序集!
    结论:一般大家应该优先选择Load方法来载入程序集,假设遇到须要使用LoadFrom方法的时候,最好改变设计而用Load方法来取代!
    另:Assembly.LoadFile 与 Assembly.LoadFrom的差别
    1、Assembly.LoadFile仅仅加载对应的dll文件,比方Assembly.LoadFile("abc.dll"),则加载abc.dll,假如abc.dll中引用了def.dll的话,def.dll并不会被加载。
    Assembly.LoadFrom则不一样,它会加载dll文件及其引用的其它dll,比方上面的样例,def.dll也会被加载。
    2、用Assembly.LoadFrom加载一个Assembly时,会先检查前面是否已经加载过同样名字的Assembly,比方abc.dll有两个版本号(版本号1在文件夹1下,版本号2放在文件夹2下),程序一開始时加载了版本号1,当使用Assembly.LoadFrom("2\\abc.dll")加载版本号2时,不能加载,而是返回版本号1.Assembly.LoadFile的话则不会做这种检查,比方上面的样例换成Assembly.LoadFile的话,则能正确加载版本号2.
    LoadFile:载入指定路径上的程序集文件的内容。LoadFrom: 依据程序集的文件名称载入程序集文件的内容。
    差别:
    LoadFile 方法用来来载入和检查具有同样标识但位于不同路径中的程序集。但不会载入程序的依赖项。
    LoadFrom 不能用于载入标识同样但路径不同的程序集。

 

总结:

Assembly.Load()方法,Assembly.LoadFrom()方法,Assembly.LoadFile()方法的差别
在C#中,我们要使用反射,首先要搞清楚下面命名空间中几个类的关系:
    System.Reflection命名空间
    (1)   AppDomain:应用程序域,能够将其理解为一组程序集的逻辑容器
    (2)   Assembly:程序集类
    (3)   Module:模块类
    (4)   Type:使用反射得到类型信息的最核心的类
    他们之间是一种从属关系,也就是说,一个AppDomain能够包括N个Assembly,一个Assembly能够包括N个Module,而一个Module能够包括N个Type.

    1,Assembly.Load()
    这种方法通过程序集的长名称(包含程序集名,版本号信息,语言文化,公钥标记)来载入程序集的,会载入此程序集引用的其它程序集,普通情况下都应该优先使用 这种方法,他的运行效率比LoadFrom要高非常多,并且不会造成反复载入的问题(原因在第2点上说明)
    使用这种方法的时候, CLR会应用一定的策略来查找程序集,实际上CLR按例如以下的顺序来定位程序集:
    ⑴假设程序集有强名称,在首先在全局程序集缓(GAC)中查找程序集。
    ⑵假设程序集的强名称没有正确指定或GAC中找不到,那么通过配置文件里的<codebase>元素指定的URL来查找
    ⑶假设没有指定强名称或是在GAC中找不到,CLR会探測特定的目录:
    如果你的应用程序文件夹是C:\AppDir,<probing>元素中的privatePath指定了一个路径Path1,你要定位的程序集是AssemblyName.dll则CLR将依照例如以下顺序定位程序集
    C:\AppDir\AssemblyName.dll
    C:\AppDir\AssemblyName\AssemblyName.dll
    C:\AppDir\Path1\AssemblyName.dll
    C:\AppDir\Path1\AssemblyName\AssemblyName.dll
    假设以上方法不能找到程序集,会发生编译错误,假设是动态载入程序集,会在执行时抛出异常!
    2,Assembly.LoadFrom()
    这种方法从指定的路径来载入程序集,实际上这种方法被调用的时候,CLR会打开这个文件,获取当中的程序集版本号,语言文化,公钥标记等信息,把他们传递给 Load方法,接着,Load方法採用上面的策略来查找程序集。假设找到了程序集,会和LoadFrom方法中指定的路径做比較,假设路径同样,该程序集 会被觉得是应用程序的一部分,假设路径不同或Load方法没有找到程序集,那该程序集仅仅是被作为一个"数据文件"来载入,不会被觉得是应用程序的一部分。 这就是在第1点中提到的Load方法比LoadFrom方法的运行效率高的原因。另外,因为可能把程序集作为"数据文件"来载入,所以使用 LoadFrom从不同路径载入同样程序集的时候会导致反复载入。当然这种方法会载入此程序集引用的其它程序集。
    3,Assembly.LoadFile()
    这种方法是从指定的文件来载入程序集,和上面方法的不同之处是这种方法不会载入此程序集引用的其它程序集!
    结论:一般大家应该优先选择Load方法来载入程序集,假设遇到须要使用LoadFrom方法的时候,最好改变设计而用Load方法来取代!
    另:Assembly.LoadFile 与 Assembly.LoadFrom的差别
    1、Assembly.LoadFile仅仅加载对应的dll文件,比方Assembly.LoadFile("abc.dll"),则加载abc.dll,假如abc.dll中引用了def.dll的话,def.dll并不会被加载。
    Assembly.LoadFrom则不一样,它会加载dll文件及其引用的其它dll,比方上面的样例,def.dll也会被加载。
    2、用Assembly.LoadFrom加载一个Assembly时,会先检查前面是否已经加载过同样名字的Assembly,比方abc.dll有两个版本号(版本号1在文件夹1下,版本号2放在文件夹2下),程序一開始时加载了版本号1,当使用Assembly.LoadFrom("2\\abc.dll")加载版本号2时,不能加载,而是返回版本号1.Assembly.LoadFile的话则不会做这种检查,比方上面的样例换成Assembly.LoadFile的话,则能正确加载版本号2.
    LoadFile:载入指定路径上的程序集文件的内容。LoadFrom: 依据程序集的文件名称载入程序集文件的内容。
    差别:
    LoadFile 方法用来来载入和检查具有同样标识但位于不同路径中的程序集。但不会载入程序的依赖项。
    LoadFrom 不能用于载入标识同样但路径不同的程序集。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/hrhguanli/p/4074059.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/376529.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

流媒体技术优化

文章目录1、下载策略优化CDN选择策略错误处理策略码率选择策略2、协议和架构优化HTTP2TCP变种拥塞控制QUIC架构流媒体协议的选择与分发体系架构的设计对优化起着关键作用。 HLS和DASH协议在点播和OTT直播服务中已逐渐占据主流&#xff0c;其思想主要是将视频转为不同码率并切为…

Android——android必看 各个控件属性(网上看到的文字,觉得挺好的,珍藏了)...

属性 值 说明 Android:orientation horizontal/vertical 设置布局水平还是垂直&#xff0c;默认是垂直 android:checked true/false 标记默认选中&#xff0c;如果是单选则选中最后一个 android:layout_gravity center/right/left/bottom/top 位置 android:gravity…

java中接口的定义与实现

1、定义接口 使用interface来定义一个接口。接口定义同类的定义类似&#xff0c;也是分为接口的声明和接口体&#xff0c;当中接口体由常量定义和方法定义两部分组成。定义接口的基本格式例如以下&#xff1a; [修饰符] interface 接口名 [extends 父接口名列表]{ [public] …

API设计笔记:pimpl技巧

pimpl pointer to implementation&#xff1a;指向实现的指针&#xff0c;使用该技巧可以避免在头文件暴露私有细节&#xff0c;可以促进API接口和实现保持完全分离。 Pimpl可以将类的数据成员定义为指向某个已经声明过的类型的指针&#xff0c;这里的类型仅仅作为名字引入&am…

C++必读书

C必读书 《Inside The C Object Model》 《Effective C》和《More Effective C》以及《Exceptional C》 《C面向对象高效编程(C Effective Object-Oriented Software Construction)》 《面向对象软件构造(Object-Oriented Software Construction)》 《设计模式(Design Patterns…

python socket编程实现的简单tcp迭代server

与c/c socket编程对照见http://blog.csdn.net/aspnet_lyc/article/details/38946915 server&#xff1a; import socketPORT 9999 BACKLOG 5 MAXLINE 1024listenfd socket.socket(socket.AF_INET,socket.SOCK_STREAM) listenfd.bind((,PORT)) listenfd.listen(BACKLOG)w…

API设计笔记:抽象基类、工厂方法、扩展工厂

文章目录抽象基类、工厂方法扩展工厂抽象基类、工厂方法 renderer.h #ifndef UNTITLED_RENDERER_H #define UNTITLED_RENDERER_H#include <string> class IRenderer { public:virtual ~IRenderer() {}virtual bool func1(const std::string& filename) 0;virtual …

《设计模式》-责任链模式

责任链模式是一种对象的行为模式【GOF95】。在责任链模式里&#xff0c;很多对象由每一个对象对其下家的用而链起来形成一条链&#xff0c;请求在这个链上传递&#xff0c;直到链上的某一个对象决定处理此请求。 发出请求的客户端并不知道链上的哪一个对象终处理这个请求&#…

ASPX的Timer位置没放正确,导致整页刷新,而不是UpdatePanel里的内容刷新。

提示&#xff1a;Timer应该放在UpdatePanel的ContentTemplate标签里&#xff0c;才行。放在外面的话&#xff0c;会导致整页刷新。转载于:https://www.cnblogs.com/xxxteam/p/3209522.html

高性能随机数:mt19937、uniform_int_distribution使用

// 例如要随机获取一个vector中的元素 // 先对vector nums进行插入数据 .... // 使用高性能随机数 mt19937 gen; // mt19937头文件是<random> 是伪随机数产生器&#xff0c;用于产生高性能的随机数 uniform_int_distribution<int> dis(0, nums.size() - 1); //uni…

【机器学习】EM最大期望算法

EM, ExpectationMaximization Algorithm, 期望最大化算法。一种迭代算法&#xff0c;用于含有隐变量(hidden variable)的概率参数模型的最大似然估计或极大后验概率估计&#xff0c;其概率模型依赖于无法观测的隐变量。 经常用在ML与计算机视觉的数据聚类领域。 EM应用&#xf…

ModuleNotFoundError: No module named ‘_ctypes‘报错解决

1、python3的安装与卸载 先删除现有的python3 https://codeantenna.com/a/Ys0TCtmqIJ 2、关于ctypes的报错问题解决 安装库后&#xff0c;重新编译python ModuleNotFoundError: No module named _ctypeshttps://www.jianshu.com/p/69681655309b 问题解决

做一个给自己手机免费发送“天气预报”信息的软件

实现一个以下截图这样的功能&#xff01;没错&#xff0c;就是你手机可以收到“免费”的天气预报短信&#xff01; 一、在做之前必须了解以下四个功能&#xff1a; 1、WebService 2、Quartz.Net&#xff08;定时任务框架&#xff09; 3、SMTP&#xff1a;简单邮件传输协议,它是…

《拾牙慧者博客检索指南》

本指南主要概括一下我的博客所涉及到的一些方面&#xff0c;以及给出每个专栏的索引&#xff0c;方便以后自己以及他人的查找相关文章。 专栏总览《春秋招面经》《基础技术栈》《数据库学习笔记》《嵌入式编程经验》《图像处理与计算机视觉经验》《机器学习笔记与数学》《算法与…

Android_Chronometer计时器

最近做一个项目用到Handler 和Message &#xff0c;开始时不是很明白&#xff0c;不了解其中的内部机制&#xff0c;所以开发起来有点难度&#xff0c;之后自己找了Android 时间服务 这一节的内容&#xff0c;总结了一点关于时间的知识&#xff0c;在这里大概写一下&#xff0c…

补码

3&#xff0e;经常使用数值编码 因为机器数在计算时&#xff0c;假设符号位和数值位同一时候參与运算&#xff0c;则可能会产生错误结果&#xff1b;而假设单独考虑符号问题&#xff0c;又会添加运算器件的实现难度。因此&#xff0c;为了使计算机可以方便地对数值进行各种算术…

置顶 | wolai博客

最近用wolai记录笔记较多&#xff0c;这里放一下我wolai的地址&#xff0c;当然csdn这边也会同时更文。 hanhan的博客

深入研究Clang(四) Clang编译器的简单分析

作者&#xff1a;史宁宁&#xff08;snsn1984&#xff09;首先我们确定下Clang编译器的具体内容和涵盖范围。之前在《LLVM每日谈之二十 Everything && Clang driver 》中曾经提到过&#xff0c;Clang driver&#xff08;命令行表示是clang&#xff09;和Clang前端&…

Expression Trees 参数简化查询

ASP.NET MVC 引入了 ModelBinder 技术&#xff0c;让我们可以在 Action 中以强类型参数的形式接收 Request 中的数据&#xff0c;极大的方便了我们的编程&#xff0c;提高了生产力。在查询 Action 中&#xff0c;我们可以将 Expression Trees 用作参数&#xff0c;通过自定义的…

为你的程序添加监听器

平时在写程序时经常会遇到监听器&#xff0c;比如按钮的click监听器&#xff0c;按键监听器等等。而android中的监听器和java中的回调函数是同一个概念&#xff0c;都是在底层代码中定义一个接口来调用高层的代码。那么什么是回调函数呢&#xff1f;网上说的是“在WINDOWS中&am…