原文:https://cloud.tencent.com/developer/article/1129356
一、對C#反射機制的理解
二、概念理解後,必須找到方法去完成,給出管理的主要語法
三、最終給出實用的例子,反射出來dll中的方法編程
參考: C#反射,MSDN編程指南c#
反射是一個程序集發現及運行的過程,經過反射能夠獲得.exe或.dll等程序集內部的信息。使用反射能夠看到一個程序集內部的接口、類、方法、字段、屬性、特性等等信息。在System.Reflection命名空間內包含多個反射經常使用的類,下面表格列出了經常使用的幾個類。
類型 做用
Assembly 經過此類能夠加載操縱一個程序集,並獲取程序集內部信息
EventInfo 該類保存給定的事件信息
FieldInfo 該類保存給定的字段信息
MethodInfo 該類保存給定的方法信息
MemberInfo 該類是一個基類,它定義了EventInfo、FieldInfo、MethodInfo、PropertyInfo的多個公用行爲
Module 該類可使你能訪問多個程序集中的給定模塊
ParameterInfo 該類保存給定的參數信息
PropertyInfo 該類保存給定的屬性信息設計
1、System.Reflection.Assembly類
經過Assembly能夠動態加載程序集,並查看程序集的內部信息,其中最經常使用的就是Load()這個方法。
Assembly assembly=Assembly.Load("MyAssembly");
利用Assembly的object CreateInstance(string) 方法能夠反射建立一個對象,參數0爲類名。
2、System.Type類
Type是最經常使用到的類,經過Type能夠獲得一個類的內部信息,也能夠經過它反射建立一個對象。通常有三個經常使用的方法可獲得Type對象。code
//利用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);
3、反射方法
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表明沒有參數
4、反射屬性
1.經過 System.Reflection.PropertyInfo 能查找到類裏面的屬性
經常使用的方法有GetValue(object,object[]) 獲取屬性值和 SetValue(object,object,object[]) 設置屬性值ip
Type type=typeof(Example); PropertyInfo[] listPropertyInfo=type.GetProperties(); foreach(PropertyInfo propertyInfo in listPropertyInfo) Cosole.WriteLine("Property name is "+ propertyInfo.Name);
2.咱們也能夠經過如下方法設置或者獲取一個對象的屬性值2.咱們也能夠經過如下方法設置或者獲取一個對象的屬性值get
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
5、反射字段
經過 System.Reflection.FieldInfo 能查找到類裏面的字段
它包括有兩個經常使用方法SetValue(object ,object )和GetValue(object) 由於使用方法與反射屬性很是類似,在此再也不多做介紹string
6、反射特性
經過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中找不到,那麼經過配置文件中的
⑶若是沒有指定強名稱或是在GAC中找不到,CLR會探測特定的文件夾:
假設你的應用程序目錄是C:\AppDir,