我目前正在使用delagates在C#中很难理解和实现事件.我习惯了Java的做事方式:
为侦听器类型定义一个接口,该接口包含许多方法定义
如果我对侦听器中定义的所有事件不感兴趣,请为该接口定义适配器类以使事情更容易
在类中定义Add,Remove和Get []方法以引发事件
定义受保护的fire方法来执行循环遍历添加的侦听器列表并调用正确方法的脏工作
这个我理解(并且喜欢!) - 我知道我可以在c#中完全相同,但似乎有一个新的(更好的?)系统用于c#.在阅读了无数教程解释c#中代表和事件的使用后,我仍然无法真正了解正在发生的事情:S
简而言之,对于以下方法,我将如何在c#中实现事件系统:
void computerStarted(Computer computer); void computerStopped(Computer computer); void computerReset(Computer computer); void computerError(Computer computer, Exception error);
^上面的方法取自我曾经制作的Java应用程序,我试图将其移植到c#.
非常感谢!
您将创建四个事件,以及用于引发它们的方法,以及一个新的基于EventArgs的类来指示错误:
public class ExceptionEventArgs : EventArgs { private readonly Exception error; public ExceptionEventArgs(Exception error) { this.error = error; } public Error { get { return error; } } } public class Computer { public event EventHandler Started = delegate{}; public event EventHandler Stopped = delegate{}; public event EventHandler Reset = delegate{}; public event EventHandlerError = delegate{}; protected void OnStarted() { Started(this, EventArgs.Empty); } protected void OnStopped() { Stopped(this, EventArgs.Empty); } protected void OnReset() { Reset(this, EventArgs.Empty); } protected void OnError(Exception e) { Error(this, new ExceptionEventArgs(e)); } }
然后,类将使用方法或匿名函数订阅事件:
someComputer.Started += StartEventHandler; // A method someComputer.Stopped += delegate(object o, EventArgs e) { Console.WriteLine("{0} has started", o); }; someComputer.Reset += (o, e) => Console.WriteLine("{0} has been reset");
有关上述内容的一些注意事项:
OnXXX方法受到保护,因此派生类可以引发事件.这并不总是必要的 - 按照您认为合适的方式进行.
在delegate{}
每个事件的声明部分只是一招,以避免做一个空检查.它为每个事件订阅了一个no-op事件处理程序
事件声明是类似字段的事件.实际创建的是变量和事件.在课堂上你看到变量; 在课外,你会看到这个事件.
有关事件的更多详细信息,请参阅我的活动/代表文章.
你必须为此定义一个委托
public delegate void ComputerEvent(object sender, ComputerEventArgs e);
ComputerEventArgs将定义如下:
public class ComputerEventArgs : EventArgs { // TODO wrap in properties public Computer computer; public Exception error; public ComputerEventArgs(Computer aComputer, Exception anError) { computer = aComputer; error = anError; } public ComputerEventArgs(Computer aComputer) : this(aComputer, null) { } }
触发事件的类将具有以下内容:
public YourClass { ... public event ComputerEvent ComputerStarted; public event ComputerEvent ComputerStopped; public event ComputerEvent ComputerReset; public event ComputerEvent ComputerError; ... }
这是您为事件分配处理程序的方法:
YourClass obj = new YourClass(); obj.ComputerStarted += new ComputerEvent(your_computer_started_handler);
你的处理程序是:
private void ComputerStartedEventHandler(object sender, ComputerEventArgs e) { // do your thing. }