C#中Assembly类的使用小结

 更新时间:2026年03月12日 09:26:26   作者:光泽雨  
本文主要介绍了C#中Assembly类详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

Assembly 类位于 System.Reflection 命名空间,表示一个可重用、可部署且可版本化的 .NET 程序集。程序集是 .NET 应用程序的基本构建块,包含了类型、资源、元数据和清单。通过 Assembly 类,你可以加载程序集、查询类型信息、动态创建实例、读取自定义特性、访问嵌入资源等。

1. 如何获取Assembly对象

1.1 静态方法(常用)

方法说明
Assembly.GetExecutingAssembly()获取当前正在执行的代码所在的程序集。
Assembly.GetCallingAssembly()获取调用当前方法的方法所在的程序集(性能稍差,慎用)。
Assembly.GetEntryAssembly()获取应用程序的入口程序集(通常是可执行文件)。
Assembly.Load()通过程序集的显示名称或字节数组加载程序集。
Assembly.LoadFrom()从指定文件路径加载程序集(会加载依赖项)。
Assembly.LoadFile()仅加载指定路径的程序集,不自动加载依赖项。
Assembly.ReflectionOnlyLoadFrom()仅用于反射(不可执行代码),.NET Core 5+ 不支持。
 using System.Reflection;
 ​
 // 1. 获取当前程序集
 Assembly asm1 = Assembly.GetExecutingAssembly();
 ​
 // 2. 通过名称加载(需已存在于应用程序域)
 Assembly asm2 = Assembly.Load("System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
 ​
 // 3. 从文件加载
 Assembly asm3 = Assembly.LoadFrom(@"C:\MyLibs\MyLibrary.dll");
 ​
 // 4. 获取入口程序集
 Assembly entryAsm = Assembly.GetEntryAssembly();

1.2 通过类型获取

 Assembly asm4 = typeof(MyClass).Assembly;

2. 常用属性

属性说明
FullName程序集完整显示名称(包含名称、版本、区域、公钥令牌)。
Location程序集文件在磁盘上的物理路径(若已加载)。
CodeBase程序集的原始 URI 位置(已过时,建议用 Location)。
ImageRuntimeVersion程序集生成时使用的 CLR 版本(如 v4.0.30319)。
EntryPoint返回程序集入口方法(如 Main 方法),若无则返回 null。
IsDynamic指示程序集是否通过反射发出(Reflection.Emit)动态生成。
Console.WriteLine(asm1.FullName);           // "MyApp, Version=1.0.0.0,        Culture=neutral, PublicKeyToken=null"
Console.WriteLine(asm1.Location);           // "C:\MyApp\bin\Debug\MyApp.exe"
Console.WriteLine(asm1.ImageRuntimeVersion);// "v4.0.30319"

3. 常用方法

3.1 类型反射

方法说明
GetTypes()获取程序集中定义的所有公共类型。
GetExportedTypes()获取程序集中定义的公共类型(可被外部访问)。
GetType(string name)通过类型全名获取 Type 对象。
GetReferencedAssemblies()获取当前程序集引用的所有程序集名称(AssemblyName)。
 Type[] allTypes = asm1.GetTypes();
 foreach (Type t in allTypes)
 {
     Console.WriteLine(t.FullName);
 }
 ​
 Type myType = asm1.GetType("MyNamespace.MyClass");

3.2 动态创建实例

方法说明
CreateInstance(string typeName)创建指定类型(区分大小写)的实例,返回 object。
CreateInstance(string typeName, bool ignoreCase)是否忽略大小写。
CreateInstance(string typeName, bool ignoreCase, BindingFlags binder, object[] args, CultureInfo culture)完整重载,支持参数传递。
// 创建无参实例
 object obj = asm1.CreateInstance("MyNamespace.MyClass");
 ​
 // 创建带参数的实例
 object obj2 = asm1.CreateInstance(
     "MyNamespace.MyClass", 
     false, 
     BindingFlags.Default, 
     null, 
     new object[] { 42, "hello" }, 
     null, 
     null);

3.3 读取自定义特性

方法说明
GetCustomAttributes()获取程序集上定义的所有自定义特性。
GetCustomAttributes(Type attributeType)获取指定类型的特性。
GetCustomAttributesData()获取特性数据(不创建实例,适用于仅反射场景)。
// 获取程序集的 AssemblyTitle 特性
 var titleAttr = asm1.GetCustomAttribute<AssemblyTitleAttribute>();
 Console.WriteLine(titleAttr?.Title);

3.4 访问嵌入资源

方法说明
GetManifestResourceNames()获取程序集中所有嵌入资源的名称。
GetManifestResourceStream(string name)获取嵌入资源的数据流(Stream)。
GetManifestResourceInfo(string name)获取资源的位置等信息。
 // 列出所有嵌入资源
 string[] resources = asm1.GetManifestResourceNames();    //获取程序集中所有嵌入资源的名称
 foreach (string res in resources)
 {
     Console.WriteLine(res);
 }
 ​
 // 读取文本资源
 using (Stream stream = asm1.GetManifestResourceStream("MyApp.Resources.Config.xml"))
 using (StreamReader reader = new StreamReader(stream))
 {
     string content = reader.ReadToEnd();
 }

注意:资源名称通常是命名空间.文件夹名.文件名,需准确指定。

3.5 安全性

方法说明
Evidence获取程序集的证据(用于安全策略,已过时)。
PermissionSet获取程序集所需的权限集。

4. 完整示例:加载外部程序集并调用方法

using System;
 using System.Reflection;
 ​
 public class Program
 {
     public static void Main()
     {
         // 1. 从文件加载程序集
         Assembly pluginAsm = Assembly.LoadFrom(@"C:\Plugins\Calculator.dll");
 ​
         // 2. 获取类型
         Type calcType = pluginAsm.GetType("CalculatorLib.Calculator");
         if (calcType == null)
         {
             Console.WriteLine("类型未找到");
             return;
         }
 ​
         // 3. 创建实例
         object calculator = Activator.CreateInstance(calcType);
         // 或使用 assembly.CreateInstance:
         // object calculator = pluginAsm.CreateInstance("CalculatorLib.Calculator");
 ​
         // 4. 调用方法
         MethodInfo addMethod = calcType.GetMethod("Add", new Type[] { typeof(int), typeof(int) });
         int result = (int)addMethod.Invoke(calculator, new object[] { 3, 5 });
         Console.WriteLine($"3 + 5 = {result}");
 ​
         // 5. 读取程序集特性
         var versionAttr = pluginAsm.GetCustomAttribute<AssemblyFileVersionAttribute>();
         Console.WriteLine($"插件版本: {versionAttr?.Version}");
     }
 }

5. 注意事项

  • 性能:反射(特别是 Invoke)比直接调用慢得多,应避免在性能敏感的循环中使用。
  • 依赖项:使用 LoadFrom 时,CLR 会尝试加载依赖程序集(从相同目录或全局程序集缓存)。如果依赖项不在预期位置,会引发 FileNotFoundException。
  • 多个上下文:Load 与 LoadFrom 将程序集加载到不同的上下文,可能导致同一程序集被加载两次。
  • 安全性:从不受信任的源加载程序集存在安全风险(可执行任意代码),建议使用 AssemblyLoadContext(.NET Core 3+)隔离。
  • 动态程序集:AssemblyBuilder 生成的动态程序集无法保存到文件(除非指定了 RunAndSave 或 Save)。
  • .NET Core/.NET 5+ 变更:
    • Assembly.CodeBase 和 Assembly.EscapedCodeBase 已过时,改用 Assembly.Location。
    • Assembly.LoadFile 在 .NET Core 中行为不同(直接加载,无依赖解析)。
    • 推荐使用 AssemblyLoadContext 进行高级程序集加载控制。

6. 总结

Assembly 类是 .NET 反射机制的核心入口之一。掌握它,你就能动态地探索和操作程序集,实现插件系统、依赖注入、模块化设计、资源提取等功能。关键要理解如何获取程序集对象、查询元数据、创建实例和访问嵌入资源,同时注意性能和安全陷阱。

通过 Assembly 类,你几乎可以获取关于程序集的一切信息,是 .NET 高级编程的必备技能。

代码文件”“运行进程”**的关系:

属性定义现场实操中的含义
Assembly.GetExecutingAssembly().Location当前代码程序集(.dll 或 .exe)所在的磁盘绝对路径。它是静态的“家”。你通过哪个文件启动,它就指哪里。
currentProcess.MainModule.FileName当前操作系统进程对应的可执行文件路径。它是动态的“身份证明”。Windows 记录了这个进程是从哪个 .exe 运行起来的。

到此这篇关于C#中Assembly类的使用小结的文章就介绍到这了,更多相关C# Assembly类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • C#简单输出日历的方法

    C#简单输出日历的方法

    这篇文章主要介绍了C#简单输出日历的方法,涉及C#针对日期与时间的简单操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-10-10
  • C#实现洗牌算法

    C#实现洗牌算法

    洗牌算法的要求是这样的:将N个数乱序后输出.由于和扑克牌的洗牌过程比较相似所以我也就称为洗牌算法了.很多地方都不自觉的需要这个算法的支持.也可以将这个算法扩展为从N个数中取出M个不重复的数(0<M<=N).今天我们看下如何用C#来实现
    2015-03-03
  • Unity3D创建圆柱体的方法

    Unity3D创建圆柱体的方法

    这篇文章主要为大家详细介绍了Unity3D创建圆柱体的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • c# richtextbox更新大量数据不卡死的实现方式

    c# richtextbox更新大量数据不卡死的实现方式

    这篇文章主要介绍了c# richtextbox更新大量数据不卡死的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • C# 通过 oledb 操作Excel实例代码

    C# 通过 oledb 操作Excel实例代码

    本篇文章主要介绍了C# 通过 oledb 操作Excel实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • C#中执行批处理文件(*.bat)的方法代码

    C#中执行批处理文件(*.bat)的方法代码

    本文介绍一下在C#中执行批处理文件(*.bat)的方法。
    2013-03-03
  • 使用C#代码接受或拒绝Excel中的修订内容(跟踪更改)

    使用C#代码接受或拒绝Excel中的修订内容(跟踪更改)

    当你将 Excel 文档发送给他人审阅时,建议开启修订/跟踪更改功能,以确保对工作表或工作簿所做的所有更改都会被记录,对于被修改的单元格,你可以查看这些更改,并决定是否接受或拒绝它们,本文将演示如何使用C#代码接受或拒绝 Excel 中的修订,需要的朋友可以参考下
    2025-11-11
  • c# SendMail发送邮件实例代码

    c# SendMail发送邮件实例代码

    这篇文章介绍了c# SendMail发送邮件实例代码,有需要的朋友可以参考一下
    2013-09-09
  • 详解WPF如何显示具有层级关系的数据

    详解WPF如何显示具有层级关系的数据

    这篇文章主要为大家详细介绍了在WPF中如何显示具有层级关系的数据,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-04-04
  • 简介C#读取XML的两种方式

    简介C#读取XML的两种方式

    在程序中访问进而操作XML文件一般有两种模型,分别是使用DOM(文档对象模型)和流模型,使用DOM的好处在于它允许编辑和更新XML文档,可以随机访问文档中的数据,可以使用XPath查询
    2013-03-03

最新评论