0

Consider the following demo

    class Program
{
    static void Main(string[] args)
    {
        MyCallBackClass myCallbackInstance = new MyCallBackClass();

        MyDelegate myDelegate = delegate() { /*Do nothing*/ };

        myDelegate += () => { Console.WriteLine("First"); };
        myDelegate += () => { Console.WriteLine("Second"); };

        myCallbackInstance.Callback = myDelegate;

        myDelegate += () => { Console.WriteLine("Third"); };

        myCallbackInstance.InvokeCallback();

        Console.ReadLine();
    }
}

delegate void MyDelegate();

class MyCallBackClass
{
    public MyDelegate Callback { get; set; }

    public void InvokeCallback()
    {
        if (Callback != null)
            Callback();
    }
}

Since a delegate is a reference type in C#, as read here Why are delegates reference types? I would expect the reference to the delegate ("Callback") in my object to point to the same delegate as the reference outside of the object ("myDelegate"). Much to my surprise, the output of this demo application is:

First
Second

, the third element added to the delegate (MulticastDelegate) is not invoked by the object.

This is not the behaviour I expect from reference types and it seems to me that the delegate is handled as if it were a value type. Where am I wrong in my assumptions? Why isn't the third delegate-element invoked?

Community
  • 1
  • 1
Michiel T
  • 302
  • 5
  • 13
  • The post you have linked to already discusses that `Delegate`s are **immutable** reference types. Just like `System.String`. – Eugene Podskal Mar 26 '15 at 18:49

2 Answers2

1

The syntax someDelegate += someOtherDelegate; does not modify either delegate. Instead, it constructs a new delegate which contains all of the methods that were present in the originals, and stores that new delegate into someDelegate; the delegates in question will contain the same methods after the call as they did before.

In your example, myCallBackInstance.Callback has stored in it a reference to a delegate containing two methods. The variable myDelegate will then have stored in it a reference to a delegate containing three methods. The latter assignment has no effect upon the earlier-created two-method delegate.

supercat
  • 77,689
  • 9
  • 166
  • 211
0

Delegates, while reference types, are immutable. The += operator doesn't mutate the value of the delegate (as doing so is impossible) rather it creates a new delegate that represents the old delegate combined with the new one and then assigns that new delegate to the variable that the += operator is used on.

Servy
  • 202,030
  • 26
  • 332
  • 449