文章出處

摘自: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對象。

  1. 利用typeof() 得到Type對象

    Type type=typeof(Example);

  2. 利用System.Object.GetType() 得到Type對象

    Example example=new Example();

    Type type=example.GetType();

  3. 利用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 }

 

 

 

 

 

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()