c# - c#中event关键字的使用

标签 c# events delegates

我想知道在 C# 中事件的确切用途是什么。我仍在学习 C#,所以我可能遗漏了一些东西,但是否可以只使用委托(delegate)。
在这个例子中,我写了一个类,它有一个从 0 到 2^64 计数的方法,每次它达到 1000 的倍数时都会引发一个事件。这是代码:

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 委托(delegate)变量声明为像这样的 public event Handler handler 的事件,会有什么不同。
抱歉,如果我有点含糊或遗漏了一些明显的东西,但我只是想知道在使用 event 而不是仅使用委托(delegate)时是否在幕后发生了其他事情,或者它是否只是为了提高可读性。

最佳答案

事件和委托(delegate)很相似,但出于充分的理由,事件受到更多限制。

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

考虑这一行:

_eventraiser.handler = SomeEventHandler;

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

如果您在此示例中使用事件而不是委托(delegate),则您不必执行任何这些操作,事实上,您甚至无法执行此操作。使用委托(delegate),您甚至可以将其传递给其他一些类,这可能非常危险。

同样适用于 Invoke,以及您可以使用委托(delegate)执行的所有其他操作:它们不适用于事件。您可以对来自外部类的事件执行的唯一操作是 +=-=,仅此而已。您可以将它们视为具有复杂 getter 和 setter 的特殊公共(public)接口(interface)的委托(delegate)。

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

关于c# - c#中event关键字的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15742098/

相关文章:

用于轮询工作线程任务完成状态的C文件描述符

c# - 如何异步设置委托(delegate)类型 UITextField.ShouldReturn?

c# - 根据 c# windows 中另一列的值对 datagrid 中的列值求和

c# - 如何将动态对象传递给 NUnit TestCase 函数?

C、2个事件和时间问题

相关元素上的 JavaScript 事件

c# - 我需要哪些 SOAP/WS-Security/WS-Addressing/etc 来发送这条消息

c# - 使用 AutoFac 根据构造函数参数名传递不同的实例

swift - 如何将委托(delegate)与 NSKeyedUnarchiver 一起使用?

c# - 当委托(delegate)传递到另一个 AppDomain 时,是否可以将委托(delegate)编码为代理?