C#中的关键字'event'是可选的吗?

Pra*_*ter 17 c# compiler-construction events

eventOne(带有关键字'event')和eventTwo(没有关键字)有什么区别?

class Program
{
    public event EventHandler eventOne;
    public EventHandler eventTwo;

    public void RaiseOne()
    {
        if (eventOne != null)
            eventOne(this, EventArgs.Empty);
    }

    public void RaiseTwo()
    {
        if (eventTwo != null)
            eventTwo(this, EventArgs.Empty);
    }

    static void Main(string[] args)
    {
        var p = new Program();
        p.eventOne += (s, e) => Console.WriteLine("One");
        p.eventTwo += (s, e) => Console.WriteLine("Two");
        p.RaiseOne();
        p.RaiseTwo();
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 20

  • eventOne是由私有字段类型支持的公共事件EventHandler.
  • eventTwo是一个公共领域的类型EventHandler.

基本上,事件包含"订阅"和"取消订阅"的想法,就像属性只包含"获取"和"设置"而不是实际存储的想法一样.(就CLR而言,事件也可以暴露"提升"方法,但C#从不使用它.忽略它.)

有关委托和事件之间差异的更多信息,请参阅我关于事件的文章(备用链接).


Sea*_*ean 17

通过使用event关键字,您可以告诉C#go generate隐藏方法,add_XXXremove_XXX用于底层委托.这可以确保使用您的类的任何人只能附加和删除该事件的委托.关键是你班外没有人举起活动,所以你可以完全控制何时会发生这种情况.

如果您不使用事件,那么您只是公开任何人都可以添加,删除和调用的公共委托.你不太可能希望除了你的班级以外的任何人进行调用.


Jho*_*re- 9

这是用于说明差异的程序,考虑到之前的答案

using System;
class Program
{
    static void Main(string[] args)
    {
        var a = new A();
        a.eventOne += (s, e) => Console.WriteLine("One");
        a.eventTwo += (s, e) => Console.WriteLine("Two");
        a.RaiseOne();
        a.RaiseTwo();
                // won't compile
        a.eventOne(null, EventArgs.Empty);
        a.eventTwo(null, EventArgs.Empty);
    }

}

class A {
    public event EventHandler eventOne;
    public EventHandler eventTwo;

    public void RaiseOne()
    {
        if (eventOne != null)
            eventOne(this, EventArgs.Empty);
    }

    public void RaiseTwo()
    {
        if (eventTwo != null)
            eventTwo(this, EventArgs.Empty);
    }
}
Run Code Online (Sandbox Code Playgroud)