在c#中使用event关键字

时间:2013-04-01 10:54:41

标签: c# events delegates

我想知道事件在c#中的确切用途。我仍然在学习c#,所以我可能会遗漏一些东西但是可以只使用代表 在这个例子中,我写了一个类,其方法从0到2 ^ 64计数,每次达到千倍数就会引发一个事件。这是代码:

namespace EventDelegate
{
class Program
{
    static void Main(string[] args)
    {
        EventRaiserClass _eventraiser = new EventRaiserClass();
        _eventraiser.handler = SomeEventHandler;
        _eventraiser.handler += AnotherEventHandler;
        _eventraiser.Loop();
        Console.Read();
    }

    static void SomeEventHandler(object sender, EventArgs args)
    {
        Console.WriteLine("Event raised");
    }

    static void AnotherEventHandler(object sendr, EventArgs args)
    {
        Console.WriteLine("Event raised (Another handler)");
    }
}

public delegate void Handler(object sender, EventArgs args);

class EventRaiserClass
{
    public Handler handler;
    public void Loop()
    {
        for (long i = 0; i < Int64.MaxValue; i++)
        {
            if ((i % 1000) == 0)
            {
                EventArgs args = new EventArgs();
                RaiseEvent(args);
                System.Threading.Thread.Sleep(1000);
            }
        }
    }

    private void RaiseEvent(EventArgs args)
    {
        if (handler != null)
            handler(this, args);
    }
}

}

如果我将handler委托变量声明为此public event Handler handler之类的事件,会有什么不同。
很抱歉,如果我有点模糊或遗漏了一些明显的东西,但我只是想知道在使用event而不仅仅是使用代表或者仅仅是出于可读性目的时是否在幕后发生了其他事情。

1 个答案:

答案 0 :(得分:2)

事件和代表是相似的,但事件受到更多限制,原因很充分。

在您的代码中,您可以使用_eventraiser.handler从外部执行各种操作。你不应该做大部分的事情。

考虑这一行:

_eventraiser.handler = SomeEventHandler;

如果您使用委托,则每次尝试附加事件处理程序(如果委托为null)时都必须检查,然后使用=初始化它,如果它不为null,您只需使用+= 添加处理程序。如果您忘记了初始化,则会得到一个空引用异常,如果您输入太多,则会覆盖以前的所有内容。

如果在此示例中使用事件而不是委托,则不必执行任何操作,事实上,您甚至无法执行此操作。有了代表,您甚至可以接受它,然后将其传递给其他类,这可能非常危险。

同样适用于Invoke,以及您可以使用委托做的所有其他事情:它们不适用于事件。对于来自外部课程的事件,您可以做的唯一事情是+=-=,就是这样。您可以将它们视为具有特殊公共接口的代理,其中包含复杂的getter和setter。

(事件也有特殊的addremove语法,但这是一个相当罕见的功能)