Search code examples
c#reflectiondelegates

How to add another (object) delegate to existing using reflection?


I don't know how to cast d for using += operator for adding next method to d.

Is here simplest way for it ? As explained first delegate lives outside the class and must be changed via reflection (not expression, expression tree, emit or so).

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");
    }
}

I have no idea how to fix it simplest way. Of course I read some articles but still no way have.

Now code works fine if I'm not using += and generates next output:

b.fn()

a.fn()


Solution

  • You need to cast delegate object to target type - B.MD here, then it should work:

    var d = (B.MD) Delegate.CreateDelegate(fi.FieldType, this, mfn);
    d += fn1;
    

    or use Delegate.Combine method to make one delegate out of two methods:

    var d = Delegate.CreateDelegate(fi.FieldType, this, mfn);
    var d1 = Delegate.CreateDelegate(fi.FieldType, this, GetType().GetMethod("fn1"));
    d = Delegate.Combine(d, d1);