如何在C#中创建属性名动态生成的对象?
问题:动态创建带有指定属性名的C#对象
我尝试用以下代码创建对象:
List<string> lltest = new List<string>{ "Id", "Nome","Valor" }; List<object> obj2 = new List<object>(); foreach (string l in lltest) { var a = new { l = "asd" }; obj2.Add(a); }
但生成的对象属性名始终是l,而我需要创建属性名来自字符串列表的对象(比如Id="asd"、Nome="asd"这类)。我的应用场景是数据表格需基于对象属性渲染列,获取DeclaredProperties时需要符合标准对象格式,使用dynamic无法满足这个需求。
解决方案:运行时动态生成强类型对象
要实现根据字符串列表动态创建带对应属性名的对象,可通过反射和System.Reflection.Emit在运行时生成自定义类型,具体步骤如下:
- 创建动态程序集与模块:用于承载要生成的动态类型
- 定义动态类:在模块中创建一个新的类
- 添加属性:遍历字符串列表,为每个属性名在动态类中创建对应的属性(包含字段、get/set方法)
- 编译并实例化类型:完成类定义后,编译类型并创建实例
- 设置属性值:为每个实例的属性赋值,最终添加到列表中
完整实现代码如下:
using System; using System.Collections.Generic; using System.Reflection; using System.Reflection.Emit; class Program { static void Main() { List<string> propertyNames = new List<string> { "Id", "Nome", "Valor" }; List<object> objList = new List<object>(); // 创建动态程序集和模块 AssemblyName assemblyName = new AssemblyName("DynamicPropertiesAssembly"); AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicPropertiesModule"); // 创建动态类 TypeBuilder typeBuilder = moduleBuilder.DefineType("DynamicPropertyObject", TypeAttributes.Public | TypeAttributes.Class); // 为每个属性名添加属性 foreach (string propName in propertyNames) { // 定义私有字段 FieldBuilder fieldBuilder = typeBuilder.DefineField($"_{propName}", typeof(string), FieldAttributes.Private); // 定义属性 PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propName, PropertyAttributes.None, typeof(string), null); // 定义get方法 MethodBuilder getMethodBuilder = typeBuilder.DefineMethod($"get_{propName}", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, typeof(string), Type.EmptyTypes); ILGenerator getIl = getMethodBuilder.GetILGenerator(); getIl.Emit(OpCodes.Ldarg_0); getIl.Emit(OpCodes.Ldfld, fieldBuilder); getIl.Emit(OpCodes.Ret); // 定义set方法 MethodBuilder setMethodBuilder = typeBuilder.DefineMethod($"set_{propName}", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, typeof(void), new Type[] { typeof(string) }); ILGenerator setIl = setMethodBuilder.GetILGenerator(); setIl.Emit(OpCodes.Ldarg_0); setIl.Emit(OpCodes.Ldarg_1); setIl.Emit(OpCodes.Stfld, fieldBuilder); setIl.Emit(OpCodes.Ret); // 将get/set方法绑定到属性 propertyBuilder.SetGetMethod(getMethodBuilder); propertyBuilder.SetSetMethod(setMethodBuilder); } // 编译动态类型 Type dynamicType = typeBuilder.CreateType(); // 创建实例并设置属性值 foreach (string propName in propertyNames) { object instance = Activator.CreateInstance(dynamicType); PropertyInfo propInfo = dynamicType.GetProperty(propName); propInfo.SetValue(instance, "asd"); objList.Add(instance); } // 验证:输出每个对象的属性名和值 foreach (var obj in objList) { foreach (PropertyInfo prop in obj.GetType().GetProperties()) { Console.WriteLine($"{prop.Name}: {prop.GetValue(obj)}"); } Console.WriteLine("---"); } } }
这段代码会生成具有指定属性名的强类型对象,调用GetType().GetProperties()(对应DeclaredProperties需求)时能正确获取到定义的属性,完全满足数据表格列渲染的场景。
内容的提问来源于stack exchange,提问作者ana mariatonia
相关产品推荐
相关产品推荐

