C# 程序集(Assembly)


程序集

程序集是代碼進行編譯是的一個邏輯單元,把相關的代碼和類型進行組合,然后生成PE文件。程序集只是邏輯上的划分,一個程序集可以只由一個文件組成,也可由多個文件組成。不管是單文件程序集還是多文件程序集,它們都由固定的結構組成

常見的兩種程序集:

  可執行文件(.exe文件)和 類庫文件(.dll文件)。

在VS開發環境中,一個解決方案可以包含多個項目,而每個項目就是一個程序集。

應用程序結構:

  包含 應用程序域(AppDomain),程序集(Assembly),模塊(Module),類型(Type),成員(EventInfo、FieldInfo、MethodInfo、PropertyInfo) 幾個層次

他們之間是一種從屬關系,也就是說,一個AppDomain能夠包括N個Assembly,一個Assembly能夠包括N個Module,一個Module能夠包括N個Type,一個Type能夠包括N個成員。他們都在System.Reflection命名空間下。【公共語言運行庫CLR】加載器 管理 應用程序域,這種管理包括  將每個程序集加載到相應的應用程序域  以及  控制每個程序集中類型層次結構的內存布局

從【應用程序結構】中不難看出程序集Assembly的組成:

MemberInfo 該類是一個基類,它定義了EventInfo、FieldInfo、MethodInfo、PropertyInfo的多個公用行為 

一個程序運行起來以后,有一個應用程序域(AppDomain),在這個應用程序域(AppDomain)中放了我們用到的所有程序集(Assembly)。我們所寫的所有代碼都會編譯到【程序集】文件(.exe .dll)中,並在運行時以【Assembly對象】方式加載到內存中運行,每個類(Class  Interface)以【Type對象】方式加載到內存,類的成員(方法,字段,屬性,事件,構造器)加載到內存也有相應的對象。

詳細:https://www.cnblogs.com/luna-hehe/p/10143748.html

程序集的結構:

程序集元數據,類型元數據,MSIL代碼,資源。

程序集元數據,程序集元數據也叫清單,它記錄了程序集的許多重要信息,是程序集進行自我說明的核心文檔。當程序運行時,CLR 通過這份清單就能獲取運行程序集所必需的全部信息。清單中主要主要包含如下信息:標識信息(包括程序集的名稱、版本、文化和公鑰等);文件列表(程序集由哪些文件組成);引用程序集列表(該程序集所引用的其他程序集);一組許可請求(運行這個程序集需要的許可)。

類型元數據,類型元數據列舉了程序集中包含的類型信息,詳細說明了程序集中定義了哪些類,每個類包含哪些屬性和方法,每個方法有哪些參數和返回值類型,等等。

MSIL代碼,程序集元數據和類型元數據只是一些輔助性的說明信息,它們都是為描述MSIL代碼而存在的。MSIL 代碼是程序集的真正核心部分,正是它們實現了程序集的功能。比如在“Animals”項目中,五個動物類的C#代碼最終都被轉換為MSIL 代碼,保存在程序集Animals.dll 中,當運行程序時,就是通過這些MSIL 代碼繪制動物圖像的。

資源,程序集中還可能包含圖像、圖標、聲音等資源。

私有程序集和共享程序集

私有程序集是僅供單個軟件使用的程序集,安裝很簡單,只需把私有程序集復制到軟件包所在文件夾中即可。而那些被不同軟件共同使用的程序就是共享程序集,.NET類庫的程序集就是共享程序集,共享程序集為不同的程序所共用,所以它的部署就不像私有程序集那么簡單,必須考慮命名沖突和版本沖突等問題。解決這些問題的辦法是把共享程序集放在系統的一個特定文件夾內,這個特定文件夾稱為全局程序集高速緩存(GAC)。這個過程可用專門的.NET 工具完成

程序集的特性

// 將 ComVisible 設置為 false 使此程序集中的類型對 COM 組件不可見。如果需要從 COM 訪問此程序集中的類型,則將該類型上的 ComVisible 屬性設置為 true。 [assembly: ComVisible(false)] // 如果此項目向 COM 公開,則下列 GUID 是用於類型庫的 ID [assembly: Guid("816a1507-8ca5-438d-87b4-9f3bef5b2481")] // 程序集的版本信息由下面四個值組成:主版本、次版本、內部版本號、修訂號 [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]

程序集的屬性信息是由特性實現的,與普通特性的不同的是,描述程序集的特性前要添加前綴“assembly:”

原文鏈接:https://www.cnblogs.com/Sweepingmonk/p/10867975.html

Assembly 程序集對象

Assembly 是一個抽象類,我們用的都是RuntimeAssembly的對象。

獲得程序集的方式:

  • 獲得當前程序域中的所有程序集
    • Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();
    • 所有用到過得aessembly。如果只是add ref了,沒有在程序中用到,AppDomain.CurrentDomain.GetAssemblies()中沒有。用到時才被JIT加載到內存。
    • 每個app都有一個AppDomain,OS不允許其他app訪問這個程序的AppDomain
  • 獲得當前對象所屬的類所在的程序集
    • this.GetType().Assembly;
    • Type對象肯定在一個assembly對象中
    • 可以通過Type對象得到程序集
  • 根據路徑加載程序集

    • Assembly.LoadFrom(assPath);
Assembly assembly = Assembly.LoadFrom(@"E:\Work\VSCode\ConsoleApp1\ClassLibrary1\bin\Debug\netstandard2.0\ClassLibrary1.dll"); Type[] allTypes = assembly.GetTypes(); Type stu = assembly.GetType("ClassLibrary1.Student"); object stu1 = Activator.CreateInstance(stu); Console.WriteLine(stu1);

Type 類型對象

Type 是一個抽象類,我們用的都是TypeInfo類的對象。

程序運行時,一個class對應一個Type類的對象。通過Type對象可以獲得類的所有信息。

獲得Type對象的方式:

  • 通過類獲得對應的Type
    • Type t1 = typeof(Person);
  • 通過對象獲得Type用assembly對象,通過類的full name類獲得type對象
    • Type t2 = person.GetType();  
    • this.GetType();
    • Type stu = assembly.GetType("ClassLibrary1.Student");
  • 獲得程序集中定義的所有的public類

    • Type[] allPublicTypes = ass1.GetExportedTypes();
  • 獲得程序集中定義的所有的類

    • Type[] allTypes = ass1.GetTypes();

Type類的屬性:

  • t.Assembly; 獲取t所在的程序集

  • t.FullName; 獲取t所對應的類的full name

  • t.Name; 獲取t所對應的類的 name

  • t.IsArray; 判斷t是否是一個數組類

  • t.IsEnum; 判斷t是否是一個枚舉類

  • t.IsAbstract; 判斷t是否是一個抽象類

  • t.IsInterface; 判斷t是否是一個interface

Type類的方法:

  • notebookInterfaceType.IsAssignableFrom(Type t);判斷t是否實現了 notebookInterfaceType 接口

  • t.IsSubclassOf(Type parent); t是否是parent的子類

  • t.IsInstanceOfType(object o); o是否是t類的對象

  • t.GetFields();  //method, property  得到所有的public的fields,methods,properties

Type類示例:

static void TypeTest1() { Person p = new Person { Name = "NaNa", Age = 5 }; Type typePerson = p.GetType(); //搜索具有指定名稱的公共屬性
            PropertyInfo pf = typePerson.GetProperty("Name"); pf.SetValue(p, "LiLi", null); Console.WriteLine(p.Name); //返回所有公共屬性
            PropertyInfo[] props = typePerson.GetProperties(); StringBuilder builder = new StringBuilder(30); foreach (PropertyInfo item in props) { builder.Append(item.Name + "=" + item.GetValue(p, null) + "\n"); } builder.Append("----------------------\n"); //返回所有公共字段
            FieldInfo[] fieIds = typePerson.GetFields(); foreach (FieldInfo item in fieIds) { builder.Append(item.Name + "=" + item.GetValue(p) + "\n"); } builder.Append("----------------------\n"); //返回所有公共方法
            MethodInfo[] methods = typePerson.GetMethods(); foreach (MethodInfo item in methods) { builder.Append(item + "\n"); } builder.Append("----------------------\n"); Console.WriteLine(builder); //返回所有公共構造函數
            ConstructorInfo[] cons = typePerson.GetConstructors(); foreach (ConstructorInfo item in cons) { //Name都是 .ctor 
                Console.WriteLine(item.Name + "\n"); //構造函數的參數個數 
                Console.WriteLine(item.GetParameters().Length + "\n"); ParameterInfo[] parames = item.GetParameters(); foreach (var pars in parames) { Console.WriteLine(pars.Name+""+pars.ParameterType); } } }
View Code

原文鏈接:https://blog.csdn.net/CJB_King/article/details/80521481

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM