我在这里遗漏了什么吗?如何通过运算符更改null事件引用?
class Foo
{
public event EventHandler<EventArgs> anEvent;
public Foo()
{
Console.WriteLine(anEvent == null); // true
anEvent += (sender, args) => { var i = 0; };
}
public static void Main(String[] args)
{
var a = new Foo();
Console.WriteLine(a.anEvent == null); // false
Console.ReadKey();
}
}
答案 0 :(得分:5)
这实际上会对代码进行一些编译器更改。编译时,它会在anEvent
周围创建一个包装器,用于添加/删除处理程序,与属性的工作方式非常相似。例如,在您的类中,编译时,您会看到(或多或少):
class Foo
{
private EventHandler<EventArgs> anEvent;
public void add_anEvent(EventHandler<EventArgs> delegateToAdd)
{
//some code to make this safe, but basically calls-ish:
anEvent = System.Delegate.Combine(anEvent, delegateToAdd);
}
public Foo()
{
Console.WriteLine(anEvent == null); // true
//your += operator is converted to a call to "add_Event" instead
add_anEvent((sender, args) => { var i = 0; };);
}
}
虽然过度简化了底层线程安全代码,但这演示了如何通过返回的System.Delegate.Combine
method处理null
案例:
一个新的委托,它有一个连接调用列表 按顺序调用 a 和 b 的列表。如果 b null ,则返回 a , 如果 a 是空引用,则返回 b ,如果是,则返回空引用 a 和 b 都是空引用。
编辑:您可以在此处阅读add
和remove
个事件访问者:https://msdn.microsoft.com/en-us/library/aa664456%28v=vs.71%29.aspx
此页面是关于实现自定义事件访问器的,但该页面上可能相关的段落可能是:
每个add-accessor-declaration和remove-accessor-declaration 对应于具有事件的单个值参数的方法 type和void返回类型。事件的隐含参数 访问者被命名为值。在事件分配中使用事件时 使用适当的事件访问器。具体来说,如果 赋值运算符是+ =然后使用add访问器,如果是 赋值运算符是 - =然后使用删除访问器。
即使您没有提供自定义add
和remove
实现,编译器也会为您填写一个基本的实现。 (就像你有空get
和set
属性一样,编译器填充一个基本的属性。在这个意义上,&#34; null&#34;通过调用这些方法为您处理案例;您不能直接在null
事件字段上操作。