具有值类型行为的回调委托

Callback delegate with value type behaviour

考虑以下演示

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

由于委托是 C# 中的引用类型,如此处所读 Why are delegates reference types? 我希望在我的 ("Callback") 中引用委托对象指向与对象外部引用相同的委托 ("myDelegate")。令我惊讶的是,这个演示应用程序的输出是:

First
Second

,添加到委托(MulticastDelegate)的第三个元素没有被对象调用。

这不是我期望的引用类型的行为,在我看来,委托的处理方式就好像它是值类型一样。我的假设哪里错了?为什么不调用第三个委托元素?

委托是不可变的,而引用类型是不可变的。 += 运算符不会改变委托的值(因为这样做是不可能的),而是创建一个新委托来表示旧委托与新委托的组合,然后将该新委托分配给变量+= 运算符用于.

语法someDelegate += someOtherDelegate; 不修改任何委托。相反,它构造了一个新的委托,其中包含原件中存在的所有方法,并将该新委托存储到 someDelegate 中;有问题的代表在调用后将包含与之前相同的方法。

在您的示例中,myCallBackInstance.Callback 已在其中存储了对包含两个方法的委托的引用。然后变量 myDelegate 将在其中存储对包含三个方法的委托的引用。后一个赋值对之前创建的双方法委托没有影响。