元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
C#运行时环境
▶
CLR基础架构
CLR组成与生命周期
托管代码执行流程
应用程序域机制
▶
程序集体系
程序集元数据结构
强名称与版本控制
动态程序集生成
▶
类型系统
CTS核心规范
值类型与引用类型
类型加载与验证
▶
编译与执行
▶
编译过程
从源代码到IL
JIT编译原理
AOT编译机制
▶
执行引擎
方法表结构
栈帧与调用约定
尾调用优化
▶
IL深入解析
IL指令集解析
元数据表结构
调试符号处理
▶
内存管理
▶
垃圾回收
分代回收算法
终结器机制
GC句柄类型
▶
内存模型
托管堆结构
栈内存管理
大对象堆优化
▶
内存优化
内存碎片处理
ArrayPool机制
Span内存视图
发布时间:
2025-03-24 10:16
↑
☰
# 程序集元数据结构 ## 程序集概述 程序集(Assembly)是.NET平台中最小的可部署和可重用的单元。它包含了编译后的代码(IL代码)、元数据、资源文件和程序集清单。本文将深入探讨程序集的元数据结构。 ## 元数据的组成 ### 1. 程序集清单(Assembly Manifest) ```csharp // 程序集属性示例 [assembly: AssemblyTitle("MyLibrary")] [assembly: AssemblyDescription("示例库")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyCulture("")] ``` 程序集清单包含以下信息: - 程序集标识(名称、版本、文化、公钥令牌) - 文件列表 - 类型引用 - 依赖项信息 ### 2. 类型元数据 ```csharp // 类型定义示例 [Serializable] public class Customer { [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public string GetFullName() { return $"{Name} (ID: {Id})"; } } ``` 类型元数据包含: - 类型定义和特性 - 成员信息(字段、属性、方法等) - 泛型参数 - 安全性信息 ## 元数据表 ### 1. 核心元数据表 ```csharp // 反射访问元数据示例 public class MetadataReader { public void InspectMetadata(Assembly assembly) { // 获取所有类型 foreach (Type type in assembly.GetTypes()) { Console.WriteLine($"类型: {type.FullName}"); // 获取方法 foreach (MethodInfo method in type.GetMethods()) { Console.WriteLine($" 方法: {method.Name}"); // 获取参数 foreach (ParameterInfo param in method.GetParameters()) { Console.WriteLine($" 参数: {param.Name}: {param.ParameterType}"); } } } } } ``` 主要的元数据表包括: 1. **TypeDef表**:定义类型信息 2. **MethodDef表**:定义方法信息 3. **Field表**:定义字段信息 4. **Param表**:定义参数信息 5. **Property表**:定义属性信息 ### 2. 引用表 ```csharp // 引用示例 using System.Linq; using System.Collections.Generic; public class ReferenceExample { public IEnumerable<string> ProcessItems(IEnumerable<string> items) { // 使用外部程序集中的类型和方法 return items.Where(item => !string.IsNullOrEmpty(item)) .Select(item => item.ToUpper()); } } ``` 引用相关的元数据表: 1. **AssemblyRef表**:外部程序集引用 2. **ModuleRef表**:模块引用 3. **TypeRef表**:类型引用 4. **MemberRef表**:成员引用 ## 自定义特性 ### 1. 定义自定义特性 ```csharp // 自定义特性示例 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class AuditAttribute : Attribute { public string Owner { get; } public DateTime LastModified { get; } public AuditAttribute(string owner) { Owner = owner; LastModified = DateTime.Now; } } // 使用自定义特性 [Audit("John Doe")] public class BusinessLogic { [Audit("Jane Smith")] public void ProcessData() { // 处理逻辑 } } ``` ### 2. 访问特性元数据 ```csharp public class AttributeInspector { public void InspectAttributes(Type type) { // 获取类型的特性 var typeAttributes = type.GetCustomAttributes(true); foreach (var attr in typeAttributes) { if (attr is AuditAttribute audit) { Console.WriteLine($"类型所有者: {audit.Owner}"); Console.WriteLine($"最后修改: {audit.LastModified}"); } } // 获取方法的特性 foreach (var method in type.GetMethods()) { var methodAttributes = method.GetCustomAttributes(true); foreach (var attr in methodAttributes) { if (attr is AuditAttribute audit) { Console.WriteLine($"方法 {method.Name} 所有者: {audit.Owner}"); } } } } } ``` ## 元数据API ### 1. 反射API ```csharp public class MetadataAPIExample { public void DemonstrateReflection() { // 获取当前程序集 Assembly assembly = Assembly.GetExecutingAssembly(); // 获取类型信息 Type type = assembly.GetType("MyNamespace.MyClass"); // 创建实例 object instance = Activator.CreateInstance(type); // 调用方法 MethodInfo method = type.GetMethod("MyMethod"); method.Invoke(instance, new object[] { "parameter" }); // 获取/设置属性 PropertyInfo property = type.GetProperty("MyProperty"); property.SetValue(instance, "new value"); // 获取特性 var attributes = type.GetCustomAttributes(); } } ``` ### 2. 元数据发射(Reflection.Emit) ```csharp public class DynamicTypeGenerator { public Type GenerateType() { // 创建动态程序集 AssemblyName assemblyName = new AssemblyName("DynamicAssembly"); AssemblyBuilder assemblyBuilder = AssemblyBuilder .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); // 创建模块 ModuleBuilder moduleBuilder = assemblyBuilder .DefineDynamicModule("DynamicModule"); // 创建类型 TypeBuilder typeBuilder = moduleBuilder .DefineType("DynamicType", TypeAttributes.Public | TypeAttributes.Class); // 添加字段 FieldBuilder fieldBuilder = typeBuilder .DefineField("_field", typeof(string), FieldAttributes.Private); // 添加属性 PropertyBuilder propertyBuilder = typeBuilder .DefineProperty("Property", PropertyAttributes.None, typeof(string), null); // 创建getter和setter MethodBuilder getMethodBuilder = typeBuilder .DefineMethod("get_Property", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, typeof(string), Type.EmptyTypes); // 生成IL代码 ILGenerator getIL = getMethodBuilder.GetILGenerator(); getIL.Emit(OpCodes.Ldarg_0); getIL.Emit(OpCodes.Ldfld, fieldBuilder); getIL.Emit(OpCodes.Ret); // 完成类型创建 return typeBuilder.CreateType(); } } ``` ## 性能优化 ### 1. 缓存反射结果 ```csharp public class ReflectionCache { private static readonly ConcurrentDictionary<string, PropertyInfo> PropertyCache = new ConcurrentDictionary<string, PropertyInfo>(); public object GetPropertyValue(object obj, string propertyName) { // 从缓存获取或添加属性信息 var property = PropertyCache.GetOrAdd( $"{obj.GetType().FullName}.{propertyName}", _ => obj.GetType().GetProperty(propertyName)); return property?.GetValue(obj); } } ``` ### 2. 委托优化 ```csharp public class DelegateOptimization { private static readonly ConcurrentDictionary<MethodInfo, Delegate> DelegateCache = new ConcurrentDictionary<MethodInfo, Delegate>(); public object InvokeMethod(object instance, MethodInfo method, params object[] parameters) { // 获取或创建委托 var delegateType = DelegateCache.GetOrAdd(method, m => CreateDelegate(m)); // 通过委托调用方法 return delegateType.DynamicInvoke( new object[] { instance }.Concat(parameters).ToArray()); } private Delegate CreateDelegate(MethodInfo method) { // 创建适当的委托类型 var parameters = method.GetParameters() .Select(p => p.ParameterType) .ToList(); Type delegateType; if (method.ReturnType == typeof(void)) { delegateType = Expression.GetActionType( new[] { method.DeclaringType } .Concat(parameters) .ToArray()); } else { delegateType = Expression.GetFuncType( new[] { method.DeclaringType } .Concat(parameters) .Concat(new[] { method.ReturnType }) .ToArray()); } return Delegate.CreateDelegate(delegateType, method); } } ``` ## 总结 程序集元数据是.NET平台的核心特性之一,它提供了丰富的类型信息和反射能力。通过理解元数据结构,我们可以: 1. 更好地理解程序集的组织结构 2. 利用反射API进行动态编程 3. 实现自定义特性来扩展元数据 4. 优化反射性能 在实际开发中,合理使用元数据可以提高程序的灵活性和可扩展性,但同时也要注意性能影响,采用适当的优化策略。