亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C# 程序集和反射詳解

2019-10-29 21:15:48
字體:
來源:轉載
供稿:網友

這里我又嘮叨幾句,大家在學習的時候,如看書或者看視頻時覺得非常爽,因為感覺基本都看得懂也都挺容易的,其實看懂是一回事,你自己會動手做出來是一回事,自己能夠說出來又是另一回事了。應該把學到的東西變成自己的東西,而不是依樣畫瓢。

在說反射之前,我們先來了解一下什么是程序集?

程序集

程序集是.net中的概念,程序集可以看作是給一堆相關類打一個包,相當于java中的jar包。

程序集包含:

  • 資源文件
  • 類型元數據(描述在代碼中定義的每一類型和成員,二進制形式)
  • IL代碼(這些都被封裝在exe或dll中)

exe與dll的區別。

exe可以運行,dll不能直接運行,因為exe中有一個main函數(入口函數)。

類型元數據這些信息可以通過AssemblyInfo.cs文件來自定義。在每一個.net項目中都存在一個AssemblyInfo.cs文件,代碼格式:

using System.Reflection;using System.Runtime.CompilerServices;using System.Runtime.InteropServices;// 有關程序集的常規信息通過以下// 特性集控制。更改這些特性值可修改// 與程序集關聯的信息。[assembly: AssemblyTitle("ReflectedDemo")][assembly: AssemblyDescription("")][assembly: AssemblyConfiguration("")][assembly: AssemblyCompany("")][assembly: AssemblyProduct("ReflectedDemo")][assembly: AssemblyCopyright("Copyright © 2017")][assembly: AssemblyTrademark("")][assembly: AssemblyCulture("")]// 將 ComVisible 設置為 false 使此程序集中的類型// 對 COM 組件不可見。 如果需要從 COM 訪問此程序集中的類型,// 則將該類型上的 ComVisible 特性設置為 true。[assembly: ComVisible(false)]// 如果此項目向 COM 公開,則下列 GUID 用于類型庫的 ID[assembly: Guid("7674d229-9929-4ec8-b543-4d05c6500863")]// 程序集的版本信息由下面四個值組成: ////   主版本//   次版本 //   生成號//   修訂號//// 可以指定所有這些值,也可以使用“生成號”和“修訂號”的默認值,// 方法是按如下所示使用“*”: // [assembly: AssemblyVersion("1.0.*")][assembly: AssemblyVersion("1.0.0.0")][assembly: AssemblyFileVersion("1.0.0.0")]

這些信息在哪里體現呢?就在我們程序集的屬性當中進行體現

C#,程序集,反射

我們平時在安裝一些CS客戶端程序的時候,在安裝目錄下面會看見許多的程序集文件。

使用程序集的好處

  • 程序中只引用必須的程序集,減小程序的尺寸。
  • 程序集可以封裝一些代碼,只提供必要的訪問接口。
  • 方便擴展。

如何添加程序集的引用?

直接添加程序集路徑或者添加解決方案中的項目引用。

當我們需要擴展一個程序的時候,你可能會直接在原有的項目中進行添加,那這樣的話,如果你的這些代碼想共享給別人使用呢?你就可以打包成一個程序集,然后別人只要通過引用你這個程序集就可以進行擴展了。像我們常見的.net第三方框架庫,如log4net、unity等等。

注意:不能添加循環引用

什么是添加循環引用?就是說A項目如果添加了B項目的項目引用,那么此時B項目不能再添加A項目的項目引用,也就是說添加項目引用時,必須是單向的,像我們常見的三層框架之間的項目引用。

反射

關于反射,你只要是做.net開發,你就一定天天在用。因為VS的智能提示就是通過應用了反射技術來實現的,還有我們常用的反編譯神器Reflector.exe,看它的名字就知道了。項目中比較常見的,是通過結合配置文件來動態實例化對象,如切換數據庫實例,或者Sprint.net的通過配置文件來實現依賴注入等。

反射技術其實就是動態獲取程序集的元數據的功能,反射通過動態加載dll,然后對其進行解析,從而創建對象,調用成員。

Type是對類的描述,Type類是實現反射的一個重要的類,通過它我們可以獲取類中的所有信息,包括方法、屬性等??梢詣討B調用類的屬性、方法。

反射的出現讓創建對象的方式發生了改變,因為過去面完創建對象都是直接通過new。

dll里面有兩部分東西:IL中間語言和metadate元素據。

在.NET中反射用到命名空間是System.Reflection,這里我先通過一個Demo來看反射能做些什么

1、  新建控制臺項目ReflectedDemo

2、  新建類庫項目My.Sqlserver.Dal

新建兩個類SqlServerHelper和SqlCmd,前者為共有類,后者為私有類

namespace My.Sqlserver.Dal{  public class SqlServerHelper  {    private int age = 16;    public string Name { get; set; }    public string Query()    {      return string.Empty;    }  }  class SqlCmd  {  }}

3、  項目ReflectedDemo,添加My.Sqlserver.Dal的項目引用,我這樣做的目的是為了方便項目ReflectedDemo中的bin目錄中時刻存在My.Sqlserver.Dal.dll程序集。

using System;using System.Reflection;namespace ReflectedDemo{  class Program  {    static void Main(string[] args)    {      //加載程序集文件,在bin目錄中查找      Assembly assembly = Assembly.Load("My.Sqlserver.Dal");      Console.WriteLine("----------------Modules----------------------");      var modules = assembly.GetModules();      foreach(var module in modules)      {        Console.WriteLine(module.Name);      }      Console.WriteLine("----------------Types----------------------");      var types = assembly.GetTypes(); //獲取程序集中所有的類型,包括公開的和不公開的      foreach(var type in types)      {        Console.WriteLine(type.Name);        Console.WriteLine(type.FullName);        var members= type.GetMembers(); //獲取Type中所有的公共成員        Console.WriteLine("----------------members----------------------");        foreach(var m in members)        {          Console.WriteLine(m.Name);        }      }      Console.WriteLine("----------------GetExportedTypes----------------------");      var exportedTypes = assembly.GetExportedTypes(); //獲取程序集中所有的公共類型      foreach(var t in exportedTypes)      {        Console.WriteLine(t.Name);      }      Console.WriteLine("----------------GetType----------------------");      var typeName= assembly.GetType("SqlServerHelper");//獲取程序集中指定名稱的類型對象      Console.WriteLine(typeName.Name);    }  }}

C#,程序集,反射

動態創建對象

通過ass.CreateInstance(string typeName) 和Activator.CreateInstance(Type t)方法

他們之間的區別

ass.CreateInstance(string typeName) 會動態調用類的無參構造函數創建一個對象,返回值就是創建的對象,如果沒有無參構造函數就會報錯。

C#,程序集,反射

Assembly assembly = Assembly.Load("My.Sqlserver.Dal");object obj = assembly.CreateInstance("My.Sqlserver.Dal.SqlServerHelper");Console.WriteLine(obj.GetType().ToString());

C#,程序集,反射

如果我們來修改SqlServerHelper類的代碼,添加如下構造函數:

    public SqlServerHelper(int age)    {      this.age = age;    }

這個時候再來運行創建實例的代碼就會報錯了,而編譯時是不報錯的。

C#,程序集,反射

所以我們一般推薦使用Activator.CreateInstance方法來創建反射對象,因為此方法有許多重載,支持將參數傳遞給構造函數。

C#,程序集,反射

此時再調用就不會出現異常了。

Type類中有三個用得比較多的方法:

  • bool IsAssignableFrom(Type t):是否可以從t賦值,判斷當前的類型變量是不是可以接受t類型變量的賦值。
  • bool IsInstanceOfType(object o):判斷對象o是否是當前類的實例,當前類可以是o的類、父類、接口
  • bool IsSubclassOf(Type t):判斷當前類是否是t的子類

Type類中還有一個IsAbstract屬性:判斷是否為抽象的,包含接口。

它們常用的原因是我們通過反射可以取到的東西太多了,我們需要對數據進行過濾。

添加類BaseSql,讓類SqlServerHelper繼承自BaseSql

然后查看調用代碼:

      bool result = typeof(BaseSql).IsAssignableFrom(typeof(SqlServerHelper));      Console.WriteLine(result);

C#,程序集,反射

   SqlServerHelper _SqlServerHelper = new SqlServerHelper(1);   bool result = typeof(SqlServerHelper).IsInstanceOfType(_SqlServerHelper);   Console.WriteLine(result);

C#,程序集,反射

      SqlServerHelper _SqlServerHelper = new SqlServerHelper(1);      bool result = typeof(SqlServerHelper).IsSubclassOf(typeof(BaseSql));      Console.WriteLine(result);

C#,程序集,反射

項目中常用的利用反射來動態切換數據庫Demo:

新建類庫項目My.Sql.IDal,并添加接口ISqlHelper。通過接口來實現數據庫操作的類的解耦,因為接口是抽象的。

  public interface ISqlHelper  {    string Query();  }

添加類庫項目My.MySql.Dal,并新增類MySqlHelper.cs

My.Sqlserver.Dal、My.MySql.Dal項目分別添加對項目My.Sql.IDal的引用。讓SqlServerHelper繼承自接口ISqlHelper

public class MySqlHelper : ISqlHelper  {    public string Query()    {       return this.GetType().ToString();    }  }  public class SqlServerHelper :ISqlHelper  {    private int age = 16;    public string Name { get; set; }    public string Query()    {      return this.GetType().ToString();    }  }

添加App.config配置項

 <appSettings>  <add key="DBName" value="My.Sqlserver.Dal,SqlServerHelper"/> </appSettings>

ReflectedDemo項目中Program.cs調用代碼:

string str = ConfigurationManager.AppSettings["DBName"];      string strAssembly = str.Split(',')[0];      string strClass=str.Split(',')[1];      Assembly assembly = Assembly.Load(strAssembly);      Type t = assembly.GetType(strAssembly + "." + strClass);      ISqlHelper obj = Activator.CreateInstance(t) as ISqlHelper;      Console.WriteLine(obj.Query());

C#,程序集,反射

這樣每次需要切換數據庫時,只要修改配置文件就可以了。

項目結構:

C#,程序集,反射

注意:反射雖然很強大,但卻是比較耗性能的,所以一般和緩存結合起來使用。

項目源碼:ReflectedDemo.zip

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持VEVB武林網!


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人h视频在线| 国产精品男人爽免费视频1| xxxx性欧美| 亚洲国产欧美精品| 成人乱色短篇合集| 亚洲精品欧美一区二区三区| 久久久精品免费| 亚洲一区二区三区乱码aⅴ蜜桃女| 91av在线免费观看视频| 日韩精品在线播放| 日韩中文字幕欧美| 亚洲精品资源美女情侣酒店| 国产97在线观看| 欧美一级片久久久久久久| 国产欧美婷婷中文| 精品国内产的精品视频在线观看| 日韩视频在线免费观看| 日韩理论片久久| 欧美大尺度激情区在线播放| 欧美国产高跟鞋裸体秀xxxhd| 91久久精品美女| 97视频免费在线观看| 午夜精品久久久久久久99热| 欧美xxxx做受欧美| 免费91麻豆精品国产自产在线观看| 欧美国产日产韩国视频| 国产成人免费91av在线| 97精品欧美一区二区三区| 成人国产精品色哟哟| 中文字幕精品在线视频| 成人精品久久一区二区三区| 色综合天天综合网国产成人网| 亚洲国产精品久久久久秋霞不卡| 久久夜精品va视频免费观看| 91精品视频在线| 欧美极品欧美精品欧美视频| 91av在线国产| 亚洲自拍另类欧美丝袜| 国产在线视频一区| 97精品欧美一区二区三区| 欧美日韩国产成人在线观看| 亚洲国产日韩欧美在线动漫| 日韩美女视频免费在线观看| 欧美日韩国产中字| 亚洲国产成人精品久久久国产成人一区| 国产精品中文字幕在线观看| 97在线看免费观看视频在线观看| 国产精品日韩欧美大师| 日韩av电影国产| 欧美影院成年免费版| 亚洲一区二区三区sesese| 一区二区三区黄色| 国产999视频| 中文字幕亚洲图片| 久久99久久亚洲国产| 久久精品色欧美aⅴ一区二区| 欧美制服第一页| 日韩a**站在线观看| 91久久夜色精品国产网站| 国产精品美女久久久久久免费| 成人国产精品日本在线| 一区二区三区国产视频| 91系列在线播放| 国产91ⅴ在线精品免费观看| 亚洲一区亚洲二区亚洲三区| 91久久在线播放| 亚洲精品电影久久久| 国产91色在线播放| 麻豆国产精品va在线观看不卡| 亚洲欧洲国产一区| 日韩视频免费中文字幕| 亚洲区bt下载| 中文国产亚洲喷潮| 久久影视三级福利片| 97在线免费观看| 午夜精品一区二区三区在线视频| 欧美国产在线电影| 亚洲最大福利网| 亚洲欧美激情精品一区二区| 欧美一区二三区| 91九色国产视频| 奇米成人av国产一区二区三区| 亚洲老头老太hd| 欧美日韩亚洲成人| 欧美激情精品久久久久久| 国产视频精品一区二区三区| 国产精品成av人在线视午夜片| 欧美色视频日本版| 欧美成人激情视频免费观看| 国产精品欧美亚洲777777| 91欧美精品成人综合在线观看| 亚洲午夜精品视频| 九色精品免费永久在线| 亚洲精品短视频| 91夜夜揉人人捏人人添红杏| 欧美成人三级视频网站| 午夜精品久久久久久久男人的天堂| 一个人看的www欧美| 国产精品69av| 高清欧美一区二区三区| 欧洲永久精品大片ww免费漫画| 久久视频在线视频| 久久久精品中文字幕| 成人亚洲综合色就1024| 在线观看国产欧美| 久久亚洲电影天堂| 国产精品中文久久久久久久| 亚洲国产91精品在线观看| 日韩精品有码在线观看| 日韩电影第一页| 日韩av日韩在线观看| 性色av一区二区三区红粉影视| 日韩免费不卡av| 成人精品视频久久久久| 欧美日韩另类字幕中文| 精品久久久久久亚洲国产300| 九九热视频这里只有精品| 久久久精品电影| 亚洲欧美日韩第一区| 亚洲精品mp4| 欧美成在线观看| 日韩精品福利在线| 国产精品综合网站| 国产精品永久免费观看| 国产视频久久久久| 777国产偷窥盗摄精品视频| 国产午夜精品理论片a级探花| 国产成人拍精品视频午夜网站| 国产精品老牛影院在线观看| 怡红院精品视频| 久久久久久高潮国产精品视| 国产一区二区三区视频| 91中文字幕一区| 日韩欧美在线视频免费观看| 在线a欧美视频| 夜夜嗨av一区二区三区免费区| 亚洲成人精品久久久| 狠狠色狠色综合曰曰| 精品中文字幕视频| 91中文在线视频| 国产亚洲一级高清| 欧美日韩久久久久| 97在线免费视频| www日韩中文字幕在线看| 午夜精品久久久久久99热软件| 国产主播在线一区| 亚洲a成v人在线观看| 亚洲天堂网站在线观看视频| 国产网站欧美日韩免费精品在线观看| 久久久中文字幕| 亚洲第一福利网| 91探花福利精品国产自产在线| 久久久91精品| 91日韩在线播放| 一区三区二区视频| 成人性生交大片免费观看嘿嘿视频| 国产成人一区二区在线| 日韩成人av在线播放| 久久精品电影一区二区| 成人国产在线视频| 欧美电影在线播放| 中文字幕欧美日韩| 97香蕉超级碰碰久久免费软件| 欧美肥臀大乳一区二区免费视频|