日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#反射与特性(一):反射基础

發布時間:2023/12/4 C# 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#反射与特性(一):反射基础 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 說明

1.1 關于反射、特性

在 《C# 7.0 本質論》中,關于這方面的知識在 《第十八章 反射、特性和動態編程》;在《C# 7.0 核心技術指南》中,這部分內容在《第19章 反射和元數據》。

[圖片來自 《C# 7.0 本質論》]

在這里我們可以獲得一些關聯性很大的技術:反射、特性、元數據;

元數據:C# 編寫的程序編譯成一個程序集,程序集會包含元數據、編譯代碼和資源。
元數據包含內容:

  • 程序或類庫中每一個類型的描述;

  • 清單信息,包括與程序本身有關的數據,以及它依賴的庫;

  • 在代碼中嵌入的自定義特性,提供與特性所修飾的構造有關的額外信息。

反射:在運行時檢查并使用元數據和編譯代碼的操作稱為反射。

一個程序集包含的內容:

[圖片來自 《C# 7.0 核心技術指南》]

2. 程序集操作

C# 編譯成的代碼會生成到 .dll 或 .exe 文件中,我們可以通過 Assembly 類,手動加載 程序集文件,實現各種操作。

Assembly 類在?System.Reflection?命名空間中。

《C# 7.0 核心技術指南》中,列出類 Assembly 類常用的屬性和方法:

接下來我們將通過代碼操作,了解 Assembly 的使用方法。

創建一個控制臺項目,并設置程序集描述信息。

2.1 獲取 程序集對象(Assembly)

微軟官方文檔建議使用的加載程序集的方式:

  • 加載程序集的建議方法是使用 Load 方法,該方法標識要由其顯示名稱(例如 "b77a5c561934e089,Version = 2.0.0.0,Culture = 中立,PublicKeyToken =")加載的程序集。該程序集的搜索遵循運行時如何定位程序集中所述的規則。

  • 利用 ReflectionOnlyLoad 和 ReflectionOnlyLoadFrom 方法,你可以加載用于反射的程序集,但不能加載用于執行的程序集。例如,可通過在32位平臺上運行的代碼來檢查面向64位平臺的程序集。

  • 對于程序集必須按路徑標識的罕見方案,會提供 LoadFile 和 LoadFrom 方法。

一般獲取程序集有三種方式:

  • Assembly.Load()

  • Assembly.LoadFrom()

  • Assembly.LoadFile()

以下方法可以獲取到當前程序引用到的程序集:

AppDomain.CurrentDomain.GetAssemblies();

輸出

System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798eConsoleApp4, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nullSystem.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3aSystem.Runtime.Extensions, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3aSystem.Console, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

2.1.1 運行時獲取程序集

通過正在運行的類型、函數等形式,去獲取程序集。

Assembly 類:public static Assembly? GetAssembly(Type type);public static Assembly GetCallingAssembly();public static Assembly? GetEntryAssembly();public static Assembly GetExecutingAssembly();Type 類:{type}.Assembly

解析說明:

位置函數說明
AssemblyGetAssembly(Type)獲取在其中定義指定類型的當前加載的程序集
AssemblyGetCallingAssembly()返回方法(該方法調用當前正在執行的方法)的 Assembly
AssemblyGetEntryAssembly()獲取默認應用程序域中的進程可執行文件。在其他的應用程序域中,這是由 ExecuteAssembly(String)執行的第一個可執行文件
AssemblyGetExecutingAssembly()獲取包含當前執行的代碼的程序集
TypeAssembly返回一個類型所在的程序集

2.1.2 使用方法

Assembly assem = typeof(Console).Assembly;Assembly ass = Assembly.GetExecutingAssembly();

2.1.3 從文件加載程序集

函數說明
LoadFrom(String)已知程序集的文件名或路徑,加載程序集
LoadFrom(String, Byte[], AssemblyHashAlgorithm)通過給定程序集文件名或路徑、哈希值及哈希算法來加載程序集
LoadFrom(String, Evidence)在給定程序集的文件名或路徑并提供安全證據的情況下,加載程序集
LoadFrom(String, Evidence, Byte[], AssemblyHashAlgorithm)通過給定程序集文件名或路徑、安全證據、哈希值及哈希算法來加載程序集

2.1.4 使用方法

Assembly ass = Assembly.LoadFrom(@"X:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.0.0\ref\netcoreapp3.0\System.Console.dll");

另外還有更多中加載程序集的方法,這些方法很偏僻,沒必要列出來(因為我不會)。

2.2 Assembly 使用

獲得 Assembly 對象后,就可以進行一系列的騷操作。

常用的 Assembly 函數可以查看圖三。

先設置兩個 Assembly 對象

Assembly assemA = typeof(Console).Assembly;Assembly assemB = Assembly.GetExecutingAssembly();

2.2.1 獲取程序集完全限定名稱

Console.WriteLine("程序集完全限定名");Console.WriteLine(assemA.FullName);Console.WriteLine(assemB.FullName);程序集完全限定名 System.Console, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ConsoleApp4, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

里面有個 PublicKeyToken 屬性,前面我們介紹了 Assembly 獲取程序集的方式,通過 PublicKeyToken ,我們也可以使用 Load 來加載程序集。

但是你可以看到上面的輸出, System.Console 有 PublicKeyToken 值,但是自己創建的項目 ConsoleApp4 沒有。

2.2.2 AssemblyName

AssmblyName 是用來完整描述程序集的類型。

AssmblyName 是用來獲取 程序集 各種信息的類,本身不具有操作功能,僅用于獲取程序集的元數據信息。

AssmblyName 實例可以使用 Assembly 的?GetName()?方法獲取。

屬性說明
CodeBase獲取或設置程序集的 URL 位置。
ContentType獲取或設置指示程序集包含的內容類型的值。
CultureInfo獲取或設置程序集支持的區域性。
CultureName獲取或設置與此程序集關聯的區域性名稱。
EscapedCodeBase獲取 URI,包括表示基本代碼的轉義符。
Flags獲取或設置該程序集的屬性。
FullName獲取程序集的全名(也稱為顯示名稱)。
HashAlgorithm獲取或設置程序集清單使用的哈希算法。
KeyPair獲取或設置用于為程序集創建強名稱簽名的加密公鑰/私鑰對。
Name獲取或設置程序集的簡單名稱。這通常(但不一定)是程序集的清單文件的文件名,不包括其擴展名。
ProcessorArchitecture獲取或設置一個值,該值標識可執行文件的目標平臺的處理器和每字位數。
Version獲取或設置程序集的主版本號、次版本號、內部版本號和修訂號。
VersionCompatibility獲取或設置與程序集同其他程序集的兼容性相關的信息。
AssemblyName assemNameA = assemA.GetName();AssemblyName assemNameB = assemB.GetName();Console.WriteLine("程序集名稱: {0}", assemNameA.Name);Console.WriteLine("程序集名稱: {0}", assemNameB.Name);// 版本Console.WriteLine("\nVersion: {0}.{1}",assemNameA.Version.Major, assemNameA.Version.Minor);Console.WriteLine("Version: {0}.{1}",assemNameB.Version.Major, assemNameB.Version.Minor);// 程序集的物理文件位置Console.WriteLine("\nAssembly CodeBase:{0}", assemA.CodeBase);Console.WriteLine("\nAssembly CodeBase:{0}", assemB.CodeBase);

輸出信息

程序集名稱: System.Console 程序集名稱: ConsoleApp4Version: 4.1 Version: 1.0Assembly CodeBase:file:///x:/Program Files/dotnet/shared/Microsoft.NETCore.App/3.0.1/System.Console.dllAssembly CodeBase:file:///X:/Users/whuanle/source/repos/ConsoleApp4/ConsoleApp4/bin/Debug/netcoreapp3.0/ConsoleApp4.dll

除了?GetName(),Assembly 類還提供了許多與成員的有關程序集的信息。例如:

  • GetName 方法返回一個 AssemblyName 對象,該對象提供對程序集顯示名稱的各個部分的訪問。

  • GetCustomAttributes 方法列出應用于程序集的特性。

  • GetFiles 方法提供對程序集清單中的文件的訪問。

  • GetManifestResourceNames 方法提供程序集清單中的資源的名稱。

2.3 獲取程序集的方式

上面說到,加載程序集的方式一般使用三種方法:

  • Assembly.Load()

  • Assembly.LoadFrom()

  • Assembly.LoadFile()

上面已經演示運行時獲取和?LoadFrom?兩種獲取方式。

下面來繼續介紹?Assembly.Load()?和?Assembly.LoadFile()?。

2.3.1 Assembly.Load()

Assembly.Load()?以強類型的方式去加載程序集,

強名稱和程序集簽名 指的是 程序集具有唯一的和不可更改的標識。

何以為強類型?通過在清單中添加如下的兩種元數據實現:

  • 屬于該程序集作者的唯一編號;

  • 程序集簽名后的散列值,以證實該程序集是由持有其唯一編號的作者生成;

關于這部分內容可以參考 《C# 7.0 核心技術指南》的《18.2 強名稱和程序集簽名》部分,這里不再贅述。

Assembly.Load()?加載程序集,同時可以自動加載程序集引用到的其它程序集,并且不會造成重復加載問題。

使用示例:

Assembly assemA = Assembly.Load("System.Console");Assembly assemB = Assembly.Load("ConsoleApp4");Assembly assemC = Assembly.Load("System.Console, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");

參考:Assembly.Load 詳解(c#)

地址:https://www.cnblogs.com/weifeng123/p/8855629.html

參考:深入了解C#反射中Assembly.Load()、Assembly.LoadFrom()、Assembly.LoadF ile ()方法

地址:https://blog.csdn.net/xuchen_wang/article/details/92773260

2.3.2 Assembly.LoadFile()

Assembly.LoadFile()?跟?Assembly.LoadFrom?的使用方法一致。

區別:?Assembly.LoadFile()只會加載指定的一個程序集;?Assembly.LoadFrom?會加載一個程序集,然后自動加載此程序集依賴的其它程序集。

總結

以上是生活随笔為你收集整理的C#反射与特性(一):反射基础的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。