摘自:http://www.cnblogs.com/leslies2/archive/2011/11/22/2257703.html
反射是一個程序集發現及運行的過程,通過反射可以得到*.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.我們也能通過反射方法執行類里面的方法
代碼:
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.我們也可以通過以下方法設置或者獲取一個對象的屬性值
代碼:
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屬性的所有特性
代碼:
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());
七、常用實例
雖然反射有很多奧妙之處,但要注意使用反射生成對象會耗費很多性能,所能必須了解反射的特性,在合適的地方使用。最常見例子就是利用單體模式與反射一并使用, 在BLL調用DAL的時候,通過一個反射工廠生成DAL實例。
1 namespace Project.Common 2 { 3 public class Factory 4 { 5 //記錄dal的對象 6 private static Hashtable dals; 7 //用assemblyString記錄DAL程序集的全名稱 8 private static string assemblyString = ConfigurationManager.AppSettings["LinqDAL"]; 9 private static Assembly assembly; 10 11 static Factory() 12 { 13 dals = new Hashtable(); 14 assembly = Assembly.Load(assemblyString); 15 } 16 17 private static object CreateInstance(string typeName) 18 { 19 //當第一次加載時,將反射對象保存于dals集合里 20 if (!dals.ContainsKey(typeName)) 21 { 22 //創建反射對象 23 object object1 = assembly.CreateInstance(typeName); 24 25 if (object1 == null) 26 throw new Exception("未能創建此對象"); 27 //把對象加入dals集合 28 dals["typeName"] = object1; 29 } 30 return dals["typeName"]; 31 } 32 33 public static IExampleDAL CreateExampleDAL() 34 { 35 return (IExampleDAL)CreateInstance(assemblyString + ".ExampleDAL"); 36 } 37 } 38 39 class Program 40 { 41 //利用工廠模式生成對象 42 static void Main(string[] args) 43 { 44 IExampleDAL iExampleDAL=Factory.CreateExampleDAL(); 45 ................. 46 Console.ReadKey(); 47 } 48 } 49 } 50 51 namespace Project.IDAL 52 { 53 public interface IExampleDAL 54 { 55 ///<summary> 56 /// 插入Example行,若插入成功,則返回新增Example的行數 57 ///</summary> 58 ///<param name="example">Example對象</param> 59 ///<returns>返回新增Example行數,默認值為-1</returns> 60 int AddExample(Example example); 61 62 ///<summary> 63 /// 更新Example表,Update成功返回已經更新的數據條數,失敗返回-1 64 ///</summary> 65 ///<param name="example">Example對象</param> 66 ///<returns>Update成功返回已經更新的數據條數,失敗返回-1</returns> 67 int UpdateExample(Example example); 68 69 ///<summary> 70 /// 刪除Example表中ID等于exampleID的行,返回已刪除行數 71 ///</summary> 72 ///<param name="exampleID">Example對象的ID值</param> 73 ///<returns>返回刪除行數</returns> 74 int DeleteExample(int exampleID); 75 76 ///<summary> 77 /// 獲取Example表的所有行 78 ///</summary> 79 ///<returns>返回Example表中的所有Example對象</returns> 80 IList<Example> GetList(); 81 82 ///<summary> 83 /// 根據ID獲取對應Example對象 84 ///</summary> 85 ///<param name="id"></param> 86 ///<returns></returns> 87 Example GetExampleByID(int id); 88 } 89 } 90 91 namespace Project.DAL 92 { 93 public class ExampleDAL:IExampleDAL 94 { 95 public int AddExample(Example example) 96 { 97 //實現AddExample方法 98 ........................... 99 } 100 .................................. 101 .................................. 102 } 103 }
文章列表