事件是委托专属的访问器
事件和属性一样,是对字段的封装。
对委托使用get,set访问器是没有意义的。
因为一旦被别人拿到了get访问器,它就可以在任何时候以任何次数调用委托。
一旦别人拿到了set访问器,别人就可以无限制地把已有地委托设置为null。
事件使用的是add访问器和remove访问器。
是只能使用+=和–=的特殊语法。
和属性一样,只能作为类成员存在。
和属性一样,本身不保存字段,可以以实例成员存在于接口中。
声明
事件的声明方式是在委托类型前加event关键字。
在后面加大括号,添加add和remove访问器。
class Foo
{
public event Action Hello
{
add
{
Console.WriteLine("hello");
}
remove
{
Console.WriteLine("你好");
}
}
}
和属性的访问器一样,在事件的访问器中会有一个参数,使用关键字value访问。
class Boo
{
private Action action;
public event Action Action
{
add { action += value; }
remove { action -= value; }
}
}
使用
事件仅允许使用+=和–=。
在使用+=时,会调用事件的add方法。右侧的值会作为参数传入add中。
在使用–=时会调用事件的remove方法。右侧的值会作为传输传入remove中。
Foo a=new Foo();
a.Hello += null;
a.Hello -= null;
自动事件
自动事件的声明和自动属性的声明不一样。在早期没有打算把事件做成和属性一样的效果,而引入了event关键字。
自动事件的声明是只写event,完全不写后面的大括号和访问器。
和自动属性一样,编译器会为你生成一个匿名委托。
并且这个事件的add和remove会对这个匿名委托进行控制。
等效于对这个委托进行+=和–=。
class Boo
{
public event Action Action;
}
并且,仅在自动实现事件的声明类,可以直接把事件当作委托使用。
通过此方式访问编译器生成的匿名委托。
(接口不行,派生类也不行,如果是抽象类以抽象形式声明的事件,也不行)
class Boo
{
public event Action Action;
public void Invoke()
{
Action?.Invoke();
}
}