当前位置:  开发笔记 > 编程语言 > 正文

C#事件处理(与Java相比)

如何解决《C#事件处理(与Java相比)》经验,为你挑选了2个好方法。

我目前正在使用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#.

非常感谢!



1> Jon Skeet..:

您将创建四个事件,以及用于引发它们的方法,以及一个新的基于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 EventHandler Error = 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事件处理程序

事件声明是类似字段的事件.实际创建的是变量事件.在课堂上你看到变量; 在课外,你会看到这个事件.

有关事件的更多详细信息,请参阅我的活动/代表文章.


我会说你只希望看到空检查,因为你不习惯这种模式 - 一旦你知道它就在那里以及为什么,我相信它会使它更具可读性.这当然是我的经历.在我看来,可读性的好处值得微小的额外内存占用(续)

2> jop..:

你必须为此定义一个委托

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.
}

推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有