编辑
2026-04-15
C#
00

目录

什么是Reflection.Emit?
核心概念解析
主要组件
IL代码生成
完整示例:学生成绩管理系统
实际应用场景
数据库表结构动态映射
配置文件动态对象创建
总结
相关技术

在C#开发中,我们经常遇到需要在运行时动态创建类型的场景。比如从数据库读取表结构动态生成实体类,或者根据用户配置动态创建数据模型。System.Reflection.Emit命名空间为我们提供了强大的动态类型创建能力。本文将通过详细的示例,带你掌握这项高级技术。

什么是Reflection.Emit?

Reflection.Emit是.NET Framework提供的一组API,允许我们在运行时动态创建程序集、模块、类型和方法。它的核心优势包括:

  • 动态性:运行时创建类型,无需预定义
  • 灵活性:根据实际需求动态调整类型结构
  • 性能:比传统反射调用更高效
  • 扩展性:可以创建复杂的类型层次结构

核心概念解析

主要组件

c#
// 程序集构建器 - 最顶层容器 AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.Run); // 模块构建器 - 包含类型定义 ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule"); // 类型构建器 - 定义具体类型 TypeBuilder typeBuilder = moduleBuilder.DefineType("ClassName", TypeAttributes.Public);

IL代码生成

IL(Intermediate Language)是.NET的中间语言,我们需要通过ILGenerator来生成IL指令:

c#
// 获取IL生成器 ILGenerator il = methodBuilder.GetILGenerator(); // 常用IL指令 il.Emit(OpCodes.Ldarg_0); // 加载第一个参数(this) il.Emit(OpCodes.Ldfld, fieldBuilder); // 加载字段值 il.Emit(OpCodes.Ret); // 返回

完整示例:学生成绩管理系统

让我们通过一个完整的学生成绩管理系统来学习动态类型创建:

c#
using System.Reflection; using System.Reflection.Emit; namespace AppLinq01 { public class Program { public static void Main() { // 示例数据 - List A (学生基本信息) List<Student> listA = new List<Student> { new Student { UserId = 1, Name = "张三", Class = "一班" }, new Student { UserId = 2, Name = "李四", Class = "二班" }, new Student { UserId = 3, Name = "王五", Class = "一班" } }; // 示例数据 - List B (学生成绩信息) List<Score> listB = new List<Score> { new Score { UserId = 1, Subject = "数学", Grade = 95 }, new Score { UserId = 1, Subject = "语文", Grade = 88 }, new Score { UserId = 1, Subject = "英语", Grade = 90 }, new Score { UserId = 2, Subject = "数学", Grade = 78 }, new Score { UserId = 2, Subject = "语文", Grade = 82 }, new Score { UserId = 3, Subject = "数学", Grade = 88 }, new Score { UserId = 3, Subject = "语文", Grade = 91 }, new Score { UserId = 3, Subject = "英语", Grade = 85 } }; // 获取所有科目 var allSubjects = listB.Select(s => s.Subject).Distinct().ToList(); // 创建动态类型 Type dynamicType = CreateDynamicType(allSubjects); // 创建结果列表 var resultList = CreateResultList(listA, listB, dynamicType, allSubjects); // 输出结果 - 遍历所有字段与值 foreach (var item in resultList) { Console.WriteLine("学生信息:"); // 获取所有属性 var properties = item.GetType().GetProperties(); // 遍历所有属性及其值 foreach (var property in properties) { var propertyName = property.Name; var propertyValue = property.GetValue(item); // 格式化显示属性名和值 Console.WriteLine($" {propertyName}: {(propertyValue == null ? "无数据" : propertyValue)}"); } Console.WriteLine(); // 空行分隔不同学生 } } private static Type CreateDynamicType(List<string> subjects) { AssemblyName assemblyName = new AssemblyName("DynamicAssembly"); AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule"); TypeBuilder typeBuilder = moduleBuilder.DefineType("StudentWithScores", TypeAttributes.Public); // Add basic properties with proper implementation CreateProperty(typeBuilder, "UserId", typeof(int)); CreateProperty(typeBuilder, "Name", typeof(string)); CreateProperty(typeBuilder, "Class", typeof(string)); // Add property for each subject with proper implementation foreach (var subject in subjects) { CreateProperty(typeBuilder, subject, typeof(double?)); } return typeBuilder.CreateType(); } private static void CreateProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType) { FieldBuilder fieldBuilder = typeBuilder.DefineField("_" + propertyName.ToLower(), propertyType, FieldAttributes.Private); PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); MethodBuilder getterBuilder = typeBuilder.DefineMethod( "get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes); ILGenerator getterIL = getterBuilder.GetILGenerator(); getterIL.Emit(OpCodes.Ldarg_0); getterIL.Emit(OpCodes.Ldfld, fieldBuilder); getterIL.Emit(OpCodes.Ret); MethodBuilder setterBuilder = typeBuilder.DefineMethod( "set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new Type[] { propertyType }); ILGenerator setterIL = setterBuilder.GetILGenerator(); setterIL.Emit(OpCodes.Ldarg_0); setterIL.Emit(OpCodes.Ldarg_1); setterIL.Emit(OpCodes.Stfld, fieldBuilder); setterIL.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getterBuilder); propertyBuilder.SetSetMethod(setterBuilder); } // 创建结果列表 private static List<object> CreateResultList(List<Student> listA, List<Score> listB, Type dynamicType, List<string> subjects) { var resultList = new List<object>(); foreach (var student in listA) { // 创建动态类型实例 var instance = Activator.CreateInstance(dynamicType); // 设置基本属性 dynamicType.GetProperty("UserId").SetValue(instance, student.UserId); dynamicType.GetProperty("Name").SetValue(instance, student.Name); dynamicType.GetProperty("Class").SetValue(instance, student.Class); // 设置成绩属性 var scores = listB.Where(s => s.UserId == student.UserId).ToList(); foreach (var subject in subjects) { var score = scores.FirstOrDefault(s => s.Subject == subject); if (score != null) { dynamicType.GetProperty(subject).SetValue(instance, score.Grade); } else { dynamicType.GetProperty(subject).SetValue(instance, null); } } resultList.Add(instance); } return resultList; } } // 定义基本类 public class Student { public int UserId { get; set; } public string Name { get; set; } public string Class { get; set; } } public class Score { public int UserId { get; set; } public string Subject { get; set; } public double Grade { get; set; } } }

image.png

实际应用场景

数据库表结构动态映射

c#
/// <summary> /// 根据数据库表结构动态创建实体类 /// </summary> public static Type CreateEntityFromDatabase(string tableName, Dictionary<string, Type> columns) { AssemblyName assemblyName = new AssemblyName($"{tableName}EntityAssembly"); AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule($"{tableName}EntityModule"); TypeBuilder typeBuilder = moduleBuilder.DefineType($"{tableName}Entity", TypeAttributes.Public | TypeAttributes.Class); // 为每个数据库列创建属性 foreach (var column in columns) { CreateAutoProperty(typeBuilder, column.Key, column.Value); } return typeBuilder.CreateType(); }

配置文件动态对象创建

c#
/// <summary> /// 根据JSON配置动态创建配置类 /// </summary> public static Type CreateConfigType(Dictionary<string, object> config) { AssemblyName assemblyName = new AssemblyName("DynamicConfigAssembly"); AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicConfigModule"); TypeBuilder typeBuilder = moduleBuilder.DefineType("DynamicConfig", TypeAttributes.Public | TypeAttributes.Class); foreach (var kvp in config) { Type propertyType = kvp.Value?.GetType() ?? typeof(object); CreateAutoProperty(typeBuilder, kvp.Key, propertyType); } return typeBuilder.CreateType(); }

总结

Reflection.Emit是C#中强大的动态编程工具,通过本文的详细介绍和实例演示,你应该能够:

  1. 理解核心概念:掌握AssemblyBuilder、ModuleBuilder、TypeBuilder的作用
  2. 创建动态类型:能够根据需求动态创建带属性和方法的类型
  3. 处理实际场景:应用到数据库映射、配置管理等实际开发中
  4. 优化性能:通过缓存和预编译提升执行效率
  5. 避免陷阱:了解常见问题并知道如何解决

在实际项目中,合理使用Reflection.Emit可以让你的代码更加灵活和可扩展。记住,这是一个高级特性,需要在性能、可维护性和复杂度之间找到平衡点。

相关技术

  • C# Reflection:反射机制基础
  • Expression Tree:表达式树,另一种动态编程方式
  • CodeDOM:代码文档对象模型
  • Roslyn:.NET编译器平台

希望这篇文章能帮助你更好地理解和使用C#的动态类型创建技术!


关键词:C# Reflection.Emit, 动态类型创建, IL代码生成, TypeBuilder, PropertyBuilder, 反射编程, .NET动态编程, AssemblyBuilder

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!