我知道+ =运算符会将一个方法添加到由Delegate基础对象维护的调用列表中
using System;
class Program
{
delegate void MyDelegate(int n);
void Foo(int n)
{
Console.WriteLine("n = {0}", n)
}
static void Main(string[] args)
{
MyDelegate d = new MyDelegate(Foo);
d += Foo; // add Foo again
d.Invoke(3); // Foo is invoked twice as Foo appears two times in invocation list
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我查看MSDN Delegate时,MulticastDelegate我找不到+ =运算符的任何定义.它是如何起作用的?自动生成编译魔术?
如果另一个线程从MyEvent取消订阅,使其为null,则会出现以下模式,用于在引发事件时避免竞争条件.
class MyClass
{
public event EventHandler MyEvent;
public void F()
{
EventHandler handler = MyEvent;
if(handler != null)
handler(this, EventArgs.Empty);
}
}
Run Code Online (Sandbox Code Playgroud)
与错误的做法相反,这种做法很容易发生这种竞争:
class MyClass
{
public event EventHandler MyEvent;
public void F()
{
if(MyEvent != null)
MyEvent(this, EventArgs.Empty);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,鉴于它System.Delegate是一个引用类型:如果MyEvent不为null,为什么会这样
EventHandler handler = MyEvent;
Run Code Online (Sandbox Code Playgroud)
似乎复制其调用列表而不是获取引用.
我希望将MyEvent委托分配给'handler'变量,然后一旦有人改变了 MyEvent,那么'handler'引用的对象也会被更改.
显然,情况并非如此,否则这个漂亮的小图案将无效.
我查看了.NET源代码,但仍然无法找到我的答案(它可能在那里,但我已经找了大约一个小时但找不到它,所以我在这里.)我也读过C#语言规范对事件和代表的评价是什么,但它没有解决这个问题.
谢谢你的时间.