頻道欄目
首頁 > 資訊 > ASP.Net > 正文

淺談.Net反射

15-03-23        來源:[db:作者]  
收藏   我要投稿

一.何為反射?

reflection; 程序集包含模塊,而模塊包含類型,類型又包含成員。反射則提供了封裝程序集、模塊和類型的對象。我們可以使用反射動態地創建類型的實例,將類型綁定到現有對象,或從現有對象中獲取類型。然后,就可以調用類型的方法或訪問其字段和屬性。

下圖很好的解釋了程序集和模塊,類型等之間的關系:

 

 

二.那些反射用到的類


1)反射核心類:System.Type類

System. Type類包裝了類型,因此是整個反射子系統的核心,這個類中包含了很多屬性和方法,使用這些屬性和方法可以在運行時得到類型的信息. Type類派生于System.Reflection.MemberInfo抽象類.(關于memberinfo,MSDN上有解釋,大家可以了解一下) 除了MemberInfo類定義的方法和屬性之外,Type類自己也添加了許多方法和屬性:如下表是常用的一些方法:


2)System.Reflection.Assembly類

通過Assembly可以動態加載程序集,并查詢程序集內部信息.Assembly中有三種方法加載程序集:Load,Loadform,LoadFile. *如果引用了命名空間,則就直接用Load方法,參數里寫上命名空間+類名就可加載。 *若僅僅知道一個dll文件,則就要用LoadFrom方法,參數里直接填寫完整的路徑。LoadFrom只能用于加載不同標識的程序集,即唯一的程序集,不能加載標識相同但路徑不同的程序集。 * Loadfile,加載指定路徑上的程序集文件;與上述兩方法不同的是:它不會加載此程序集中引用的其他的程 序集,且不會加載相同標識的程序集。 舉例:
      //Assembly通過此類可以加載操縱一個程序集,并獲取程序集內部信息
      Assembly assembly = Assembly.Load("MyAssembly"); //引用命名空間
      Assembly assembly2 = Assembly.LoadFrom("D:\testDll.dll"); 
      Assembly dll = Assembly.LoadFile(Environment.CurrentDirectory + "\\testDll.dll");                                           //通過dll文件去反射其中所有的類型,但不會加載引用的程序集

 

三.如何使用反射?

1)要引用的程序集和需要程序集的程序在同一目錄時,不需要加載程序集,直接可以獲取其中的類型.舉例:

 

      Type math = Type.GetType("testDll.Math", true);    //獲取類型
     
      MethodInfo method = math.GetMethod("add");  //獲取testdll.math中的方法add
      int count = (int)method.Invoke(null, new object[] { 10, 20 }); //給add方法傳參數并去調用方法add
               
      Console.WriteLine("Invoke Method:" + count.ToString()); 
      Console.ReadLine();

 

2)要引用的程序集合需要程序集不在同一目錄中時,先要加載程序集,才能獲取其中的類和類的方法等。舉例:

      Assembly dll = Assembly.LoadFile(Environment.CurrentDirectory + "\\testDll.dll");   //通過dll文件去反射其中所有的類型,但不會加載引用的程序集
          //Environment.CurrentDirectory 屬性:獲取或設置當前工作目錄的完全限定路徑              
      Type math = dll.GetType("testDll.Math", true);    //獲取類型
     
      MethodInfo method = math.GetMethod("add");  //獲取testdll.math中的方法add
      int count = (int)method.Invoke(null, new object[] { 10, 20 }); //給add方法傳參數并去調用方法add
               
      Console.WriteLine("Invoke Method:" + count.ToString()); 
      Console.ReadLine();

 

 

 

3)反射+配置文件

看過大話設計模式的,都知道在抽象工廠模式中.小菜在大鳥的指點下,用簡單工廠,再用反射,再用配置文件,一步步將抽象工廠改裝, 使得抽象工廠的缺點和個各類之間的耦合性都大大降低.

 

不用反射+配置文件時,抽象工廠的問題是:
*如果需要增加多個數據庫,就要增加多個類,更麻煩。


在使用反射+配置文件后,抽象工廠的改變是:
*如果需要更換數據庫,不需改變代碼,只需要修改配置文件中DB的值。

小結:反射技術的使用去除了switch或if,解除分支判斷的耦合。在這里,反射可以說是簡化了工廠的實現。

4)項目實踐

在前段時間的項目開發中,就用到了反射。這里的用法和上述介紹的情況是一樣的。用Assembly類的Load方法去加載程序集,用GetType去獲取類型,GetMethod去獲取方法,Invoke去調用方法,最后用SaveChanges去提交數據。舉例:

        //EF:就是讓EF上下文保存了一下。不適合于集群(后期使用key,value保存在分布式緩存中,key為guid)
        public int SaveChanges()
        {
            //return DbContextFactory.GetCurrentDbContext().SaveChanges();


            string strAssembly = ConfigurationManager.AppSettings["DalAssembly"];
            string strDbContextFactoryclassFulleName = ConfigurationManager.AppSettings["DbContextFactoryclassFulleName"];


            Assembly assembly = Assembly.Load(strAssembly);
            Type type = assembly.GetType(strDbContextFactoryclassFulleName);
            MethodInfo methodInfo = type.GetMethod("GetCurrentDbContext");
            return ((DbContext)methodInfo.Invoke(null, null)).SaveChanges();
        }

四.為什么要用反射?

反射與引用

相比較下,引用執行效率高,但是當你引用的dll文件很多的時候,一遍遍的引用dll...,那就不是什么好事了。 反射呢,雖執行效率低,但在上述情況出現時,它只需動態反射一次dll文件,不用去管dll文件時新增還是減少的情況了,有點一勞永逸的味道。

 

在真正用的過程中,反射回合委托,泛型,特性等等結合使用,這都是需要進一步研究學習的地方

 

 


 

相關TAG標簽
上一篇:C#學習之步步高(一)同名方法之間的關系
下一篇:輸出九九乘法表并輸出坐標
相關文章
圖文推薦

關于我們 | 聯系我們 | 廣告服務 | 投資合作 | 版權申明 | 在線幫助 | 網站地圖 | 作品發布 | Vip技術培訓 | 舉報中心

版權所有: 紅黑聯盟--致力于做實用的IT技術學習網站

美女MM131爽爽爽毛片