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

如何通过Reflection.Emit在运行时为已有类添加属性?

问题分析与解决方案

核心问题

无法通过Reflection.Emit直接修改已加载的现有类——CLR不允许类被加载到AppDomain后修改其结构(包括添加字段、属性)。你当前的代码只是在动态程序集中创建了一个同名的新类,和原程序集里的MyClass毫无关联,所以原实例的属性不会有任何变化。

你的代码问题点

这段代码里的tb = mb.DefineType("MyClass")生成的是动态程序集内的全新类型,和你原本的MyClass属于不同程序集、不同Type对象,因此:

  • 后续创建的new MyClass()还是原类型的实例,不会包含动态添加的testProp
  • 动态生成的类只有调用tb.CreateType()后才会存在,且需通过该Type创建实例才能使用

可行替代方案

方案1:动态生成子类扩展原类

既然不能修改原类,可以通过继承原类,动态生成子类来添加新属性/字段:

var originalType = typeof(MyClass);
var assemblyName = new AssemblyName("DynamicExtensions");
AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder mb = ab.DefineDynamicModule(assemblyName.Name);

// 生成继承自MyClass的子类
TypeBuilder tb = mb.DefineType(
    "MyClassExtended",
    TypeAttributes.Public | TypeAttributes.Class,
    originalType);

// 给子类添加属性
AddProperty(tb, "testProp", typeof(string));

// 创建动态类型并实例化
Type extendedType = tb.CreateType();
var extendedInstance = Activator.CreateInstance(extendedType) as MyClass;

// 验证属性存在
Console.WriteLine(extendedType.GetProperties().Length);
foreach (var prop in extendedType.GetProperties())
{
    Console.WriteLine(prop.Name);
}

方案2:使用ExpandoObject(弱类型场景)

如果不需要强类型,可以用ExpandoObject包装原类实例,动态添加属性:

dynamic expando = new ExpandoObject();
var originalInstance = new MyClass();

// 拷贝原类属性到Expando
foreach (var prop in originalInstance.GetType().GetProperties())
{
    ((IDictionary<string, object>)expando)[prop.Name] = prop.GetValue(originalInstance);
}

// 添加新属性
expando.testProp = "new value";

// 使用动态属性
Console.WriteLine(expando.testProp);

方案3:装饰器模式(强类型扩展)

定义一个装饰类包装原实例,添加额外属性:

public class MyClassDecorator
{
    private readonly MyClass _original;
    public string testProp { get; set; }

    public MyClassDecorator(MyClass original)
    {
        _original = original;
    }

    // 暴露原类的属性/方法
    public string OriginalProp => _original.OriginalProp;
}

// 使用示例
var original = new MyClass();
var decorated = new MyClassDecorator(original);
decorated.testProp = "test";
Console.WriteLine(decorated.testProp);

内容的提问来源于stack exchange,提问作者Ivan Kolesnyk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 22:18:21