具有值类型行为的回调委托
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
将在其中存储对包含三个方法的委托的引用。后一个赋值对之前创建的双方法委托没有影响。
考虑以下演示
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
将在其中存储对包含三个方法的委托的引用。后一个赋值对之前创建的双方法委托没有影响。