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

如何通过反射向已有委托添加另一个委托实例?

问题描述

我不清楚如何转换变量d以使用+=运算符向其添加新方法。是否存在最简解决方案?如前文所述,初始委托存在于类外部,必须通过反射修改(不得使用表达式、表达式树、Emit等方式)。

当前代码在不使用+=时可正常运行,输出内容为:

b.fn()
a.fn()

相关代码如下:

using System;
using System.Reflection;

public class A
{
    public void fn()
    {
        Console.WriteLine ("a.fn() \n");
    }
    public void fn1()
    {
        Console.WriteLine ("a.fn1()");
    }
    void start()
    {
         var cb = new B();
         FieldInfo fi  = cb.GetType().GetField("mD");
         MethodInfo mfn  = this.GetType().GetMethod("fn");
         
         object d = System.Delegate.CreateDelegate( fi.FieldType, this, mfn);
//              d += System.Delegate.CreateDelegate( fi.FieldType, this, mfn1); 
// Line above give me an error CS0019: Operator '+=' cannot be applied to operands of type 'object' and 'Delegate'
// I think it due d is object not MD()


        fi.SetValue(cb, d);
        cb.tst();
    }
    
    public static void Main(string[] args)
    {
        var ca = new A();
        ca.start();
    }
}
public class B
{
    public delegate void    MD();
    public          MD mD ;
    public B()
    {
        mD = fn;
        tst();
    }
    public void tst()
    {
        mD();
    }
    void fn()
    {
         Console.WriteLine ("b.fn() \n");
    }
}
解决方案

因为变量d被声明为object类型,无法直接使用+=运算符(该运算符仅对具体委托类型或Delegate基类有效),最简方案是使用Delegate.Combine方法来合并委托——它是+=运算符的底层实现,能自动处理委托链拼接,具体修改如下:

将注释掉的报错行替换为:

// 先将d强制转为Delegate类型,再与新创建的委托合并
d = Delegate.Combine((Delegate)d, Delegate.CreateDelegate(fi.FieldType, this, GetType().GetMethod("fn1")));

完整修改后的start方法代码:

void start()
{
     var cb = new B();
     FieldInfo fi  = cb.GetType().GetField("mD");
     MethodInfo mfn  = this.GetType().GetMethod("fn");
     
     object d = System.Delegate.CreateDelegate(fi.FieldType, this, mfn);
     // 合并委托
     d = Delegate.Combine((Delegate)d, Delegate.CreateDelegate(fi.FieldType, this, GetType().GetMethod("fn1")));

    fi.SetValue(cb, d);
    cb.tst();
}

说明

  • Delegate.Combine是.NET官方提供的委托合并方法,+=运算符本质就是该方法的语法糖。
  • 由于d是object类型,必须先强制转换为Delegate基类才能传入Combine方法。
  • 合并后的委托仍保持原委托类型(此处为B.MD),可直接通过SetValue赋值给目标字段。

修改后运行代码,输出结果为:

b.fn()
a.fn()
a.fn1()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:45:05