原文:https://cloud.tencent.com/developer/article/1129356

1、对C#反射机制的理解

2、概念理解后,必须找到方法去完成,给出管理的主要语法

3、最终给出实用的例子,反射出来dll中的方法

参考: C#反射,MSDN编程指南

反射是一个程序集发现及运行的过程,通过反射可以得到.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[]) 设置属性值

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)就可反射出一个类里面的特性,以下例子可以反射出一个类的所有特性

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中找不到,那么通过配置文件中的元素指定的URL来查找

⑶如果没有指定强名称或是在GAC中找不到,CLR会探测特定的文件夹:

假设你的应用程序目录是C:\AppDir,元素中的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 不能用于加载标识相同但路径不同的程序集。

C#中的反射解析及使用(转)的更多相关文章

  1. golang中的反射解析结构体标签tag

    package main import ( "fmt" "reflect" ) type resume struct { // 反射解析结构体标签tag Nam ...

  2. [C#反射]C#中的反射解析及使用.

    1.对C#反射机制的理解2.概念理解后,必须找到方法去完成,给出管理的主要语法3.最终给出实用的例子,反射出来dll中的方法 参考: C#反射,MSDN编程指南 反射是一个程序集发现及运行的过程,通过 ...

  3. 第89节:Java中的反射技术

    第89节:Java中的反射技术 反射技术是动态的获取指定的类,和动态的调用类中的内容(没有类前就可以创建对象,将对象的动作完成,这就是动态的获取指定的类). 配置文件把具体实现的类名称定义到配置文件中 ...

  4. Javascript中的反射机制(五)

    一: 什么是反射机制 反射机制指的是程序在运行时能够获取自身的信息.例如一个对象能够在运行时知道自己有哪些方法和属性. 二: 在JavaScript中利用for(…in…)语句实现反射 在JavaSc ...

  5. python3反射解析

    python反射解析   一. 简介 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某 ...

  6. 【Java基础】java中的反射机制与动态代理

    一.java中的反射机制 java反射的官方定义:在运行状态下,可以获取任意一个类的所有属性和方法,并且可通过某类任意一对象实例调用该类的所有方法.这种动态获取类的信息及动态调用类中方法的功能称为ja ...

  7. 详解C#中的反射

    反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的生理情况.这是如何做到的呢?B超是B ...

  8. python中的反射

    在绝大多数语言中,都有反射机制的存在.从作用上来讲,反射是为了增加程序的动态描述能力.通俗一些,就是可以让用户参与代码执行的决定权.在程序编写的时候,我们会写很多类,类中又有自己的函数,对象等等.这些 ...

  9. .net中的反射(转载)

    原文地址:http://www.cnblogs.com/Stephenchao/p/4481995.html 两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的 ...

随机推荐

  1. windows 启动停止 java进程

    本案例以 xxx.jar    为列子 我们一般启动的jar 在任务管理器中查看进程都是javaw.exe ,无法用命令来 kill,所以我们得给自己的java 进程设置个新 title 1:  首先 ...

  2. .net js有数据 但是跳转不到操作页

    首先看的是:js  的 model 传了 两个参数 在接着打开操作页 可以看到,这一页有三个参数.id是可以自动生成的,所以不让他显示,去掉 如上就可以了 ,传的参数数量不对   ,下次注意的撒!

  3. JS 全选

    第一种情况 1. 首先得有全选  checkall <input type="checkbox" class="checkAll" value=" ...

  4. CentOS7、REHL7的firewalld防火墙使用简单说明

    title: CentOS7.REHL7的firewalld防火墙使用简单说明 categories: Linux tags: - Linux timezone: Asia/Shanghai date ...

  5. Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'系列一:

    从库报这个错误:Got fatal error 1236 from master when reading data from binary log: 'Could not find first lo ...

  6. Python加密保护-对可执行的exe进行保护

    Python 是一种面向对象的解释型计算机程序设计语言,Python 语言写的程序不需要编译成二进制代码,可以直接从源代码运行程序. 在计算机内部,Python解释器把源代码转换成称为字节的中间形式, ...

  7. JMeter-性能测试监控(解决.sh文件的启动)

    下载插件 https://jmeter-plugins.org/downloads/old/ 已安装了jmeter-plugins-manager,装的这个不知道生没生效.... 2.问题:启动就显示 ...

  8. sping Bean 的生命周期是如何被管理

    1. 实例化一个Bean,也就是我们通常说的new 2. 按照Spring上下文对实例化的Bean进行配置,也就是IOC注入 3. 如果这个Bean实现了BeanNameAware接口,会调用它实现的 ...

  9. asp.net导入后台代码

    public void Upload(string information){ int Bank = 0; for (int i = 0; i <Request.Files.Count; i++ ...

  10. vue生命周期钩子函数

    <template> <div> <h2>this is from C.vue</h2> </div> </template> ...