事件基于委托概念,委托基本上是方法签名的定义。就像在接口中定义方法签名一样,但您不需要在接口中实现它们,而是在所有继承该接口的类中实现。
委托是一个方法签名的定义,可以为其定义任意数量的方法体,例如,给定此委托(方法签名定义):
public delegate void ChangingHandler (object sender, CarArgs ca);
您可以使用此委托(方法签名定义)来定义函数体,如下所示:
public void SomeMethodWhichCreatesADelegateBody()
{
ChangingHandler myChangingHandler = new ChangingHandler(
delegate(object sender, EventArgs e) { }
);
}
这是一种旧的定义委托的方式,现在更推荐使用lambda表达式来创建方法体,使代码更易读。但这并不影响问题的解决。
现在可以将事件想象成一个带有一系列方法体的委托(方法签名定义),这些方法体被称为订阅事件,订阅方法体到事件的语法是+=
,同时也有从事件订阅中移除方法体的语法-=
因此,这段代码定义了一个ChangingHandler委托(方法签名定义)的方法体数组:
public event ChangingHandler Change;
你可以通过调用一个方法将body(将它们添加到数组中)订阅到这个分组中:
public void SomeMethodWhichSubscribesADelegateBodyToAnEvent()
{
ChangingHandler myChangingHandler = new ChangingHandler(
delegate(object sender, EventArgs e) { }
);
Change += myChangingHandler;
}
现在事件具有方法体数组的整个原因是,您可以定义和添加任意数量的方法体,以便每当该对象内部发生事件时,该对象可以执行所有这些方法来完成任何您想要完成的操作。拥有该事件的对象可以像这样执行所有这些方法:
if (Change != null) // You wouldn't access an array without making sure it wasn't null, would you?
{
Change(this, new CarArgs()); // This executes every method body in it's array using the signature definition the delegate defined.
// The delegate simply exists so this code knows the method signature
// so it can know how to call those method body's for you.
}
car.Change += car_Change;
(这相当惯用)。 - bruceboughton