委托声明了一个函数签名,当它用作类上的事件时,它还充当登记调用目标的集合。事件上的 += 和 -= 语法用于将目标添加到列表中。
给定以下用作事件的委托:
// arguments for events
public class ComputerEventArgs : EventArgs
{
public Computer Computer { get; set; }
}
public class ComputerErrorEventArgs : ComputerEventArgs
{
public Exception Error { get; set; }
}
// delegates for events
public delegate void ComputerEventHandler(object sender, ComputerEventArgs e);
public delegate void ComputerErrorEventHandler(object sender, ComputerErrorEventArgs e);
// component that raises events
public class Thing
{
public event ComputerEventHandler Started;
public event ComputerEventHandler Stopped;
public event ComputerEventHandler Reset;
public event ComputerErrorEventHandler Error;
}
您将使用以下内容订阅这些事件:
class Program
{
static void Main(string[] args)
{
var thing = new Thing();
thing.Started += thing_Started;
}
static void thing_Started(object sender, ComputerEventArgs e)
{
throw new NotImplementedException();
}
}
尽管参数可以是任何东西,但 object sender 和 EventArgs e 是一个使用非常一致的约定。+= thing_started 将首先创建一个指向目标方法的委托实例,然后将其添加到事件中。
在组件本身上,您通常会添加方法来触发事件:
public class Thing
{
public event ComputerEventHandler Started;
public void OnStarted(Computer computer)
{
if (Started != null)
Started(this, new ComputerEventArgs {Computer = computer});
}
}
如果没有代表添加到事件中,您必须测试 null。但是,当您进行方法调用时,将调用所有已添加的委托。这就是为什么事件的返回类型为 void - 没有单一的返回值 - 因此,要反馈信息,您将拥有 EventArgs 上的属性,事件处理程序将更改这些属性。
另一个改进是使用通用的 EventHandler 委托,而不是为每种类型的 args 声明一个具体的委托。
public class Thing
{
public event EventHandler<ComputerEventArgs> Started;
public event EventHandler<ComputerEventArgs> Stopped;
public event EventHandler<ComputerEventArgs> Reset;
public event EventHandler<ComputerErrorEventArgs> Error;
}