考虑以下演示
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)的第三个元素。
这不是我期望的引用类型的行为,在我看来,委托被处理就好像它是一个值类型。我的假设在哪里错了?为什么不调用第三个委托元素?
答案 0 :(得分:1)
语法someDelegate += someOtherDelegate;
不会修改任何委托。相反,它构造一个新的委托,其中包含原始文件中存在的所有方法,并将新委托存储到someDelegate
;有问题的代表将在调用之后包含与之前相同的方法。
在您的示例中,myCallBackInstance.Callback
在其中存储了对包含两个方法的委托的引用。变量myDelegate
将在其中存储对包含三个方法的委托的引用。后一个赋值对先前创建的双方法委托没有影响。
答案 1 :(得分:0)
代理虽然引用类型是不可变的。 +=
运算符不会改变委托的值(因为这样做是不可能的),而是创建一个新委托,表示旧委托与新委托相结合,然后将新委托分配给变量+ =运算符用于。