You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#运行时动态创建类后如何为新类属性赋值并实现数据填充

实现动态类属性赋值的具体方案

1. 调整动态类创建方法,返回构造完成的类型

你现有createType方法没有返回生成的类类型,首先修改方法定义,编译完成后返回对应的Type实例供后续使用:

static Type createType(string name, IDictionary<string, Type> props)
{
    var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } });
    var parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" }, "Test.Dynamic.dll", false);
    parameters.GenerateExecutable = false;
    // 增加这行,允许在内存中直接访问生成的类型
    parameters.GenerateInMemory = true;

    var compileUnit = new CodeCompileUnit();
    var ns = new CodeNamespace("Test.Dynamic");
    compileUnit.Namespaces.Add(ns);
    ns.Imports.Add(new CodeNamespaceImport("System"));

    var classType = new CodeTypeDeclaration(name);
    classType.Attributes = MemberAttributes.Public;
    ns.Types.Add(classType);

    foreach (var prop in props)
    {
        var fieldName = "_" + prop.Key;
        var field = new CodeMemberField(prop.Value, fieldName);
        classType.Members.Add(field);

        var property = new CodeMemberProperty();
        property.Attributes = MemberAttributes.Public | MemberAttributes.Final;
        property.Type = new CodeTypeReference(prop.Value);
        property.Name = prop.Key;
        property.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName)));
        property.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName), new CodePropertySetValueReferenceExpression()));
        classType.Members.Add(property);
    }

    var results = csc.CompileAssemblyFromDom(parameters, compileUnit);
    results.Errors.Cast<CompilerError>().ToList().ForEach(error => Console.WriteLine(error.ErrorText));
    
    // 编译成功后返回生成的类型
    if (!results.Errors.HasErrors)
    {
        return results.CompiledAssembly.GetType($"Test.Dynamic.{name}");
    }
    return null;
}

2. 两种属性赋值实现方式

方式1:使用dynamic关键字简化操作(最接近你需要的直接赋值写法)

C#的dynamic类型可以绕过编译时类型检查,运行时直接访问动态类的属性:

// 生成动态类类型
Type blogPostType = createType("BlogPost", new Dictionary<string, Type>() {
    { "Title", typeof(string) },
    { "Text", typeof(string) },
    { "Tags", typeof(string[]) }
});

// 实例化动态类,用dynamic接收
dynamic post = Activator.CreateInstance(blogPostType);
// 直接赋值属性,和静态类写法几乎一致
post.Title = "Title 1";
post.Text = "测试内容";
post.Tags = new string[] { "C#", "动态类" };

// 生成实例列表
List<dynamic> postList = new List<dynamic>();
postList.Add(post);

// 读取属性也可以直接写
Console.WriteLine(postList[0].Title);

方式2:纯反射赋值(不需要依赖dynamic)

如果不想用dynamic,可以通过反射的SetValue方法赋值:

object post = Activator.CreateInstance(blogPostType);
// 给Title属性赋值
blogPostType.GetProperty("Title").SetValue(post, "Title 1");
// 给Text属性赋值
blogPostType.GetProperty("Text").SetValue(post, "测试内容");

// 列表用List<object>存储
List<object> postList = new List<object>();
postList.Add(post);

// 读取属性
var title = blogPostType.GetProperty("Title").GetValue(postList[0]);

3. 批量填充你示例中的JSON结构数据

对应你给出的多属性数组结构,可以用如下方式批量生成实例列表:

// 你的示例数据结构,用字典模拟
var data = new Dictionary<string, Array>()
{
    { "ID", new int[] {1,2,3} },
    { "Name", new string[] {"A","B","C"} },
    { "Weight", new int[] {10,20,30} }
};

// 先根据字段生成动态类
var class1Type = createType("Class1", new Dictionary<string, Type>()
{
    {"ID", typeof(int)},
    {"Name", typeof(string)},
    {"Weight", typeof(int)}
});

List<dynamic> class1List = new List<dynamic>();
// 遍历数组长度,批量生成实例
int dataCount = data["ID"].Length;
for (int i = 0; i < dataCount; i++)
{
    dynamic item = Activator.CreateInstance(class1Type);
    foreach (var prop in data)
    {
        // 给对应属性赋值对应索引的数值
        class1Type.GetProperty(prop.Key).SetValue(item, prop.Value.GetValue(i));
    }
    class1List.Add(item);
}

注意事项

  • 动态编译生成的属性名大小写敏感,赋值时需要和定义时的名称完全一致
  • 赋值时需要保证数据类型和定义的属性类型匹配,否则会触发运行时异常
  • 如果你不需要把动态类持久化生成dll,parameters.GenerateInMemory设为true就不需要生成本地文件

内容的提问来源于stack exchange,提问作者J.Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 01:27:01