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

时间:2009-04-02 21:42:11

标签: c# events compiler-construction

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();
    }
}

3 个答案:

答案 0 :(得分:20)

  • eventOne是由EventHandler类型的私有字段支持的公共事件
  • eventTwoEventHandler类型的公开字段

基本上,只有 的事件封装了“subscribe”和“unsubscribe”的思想,其方式与属性仅封装“get”和“set”的思想而不是实际存储的方式相同。 (就CLR而言,事件也可以暴露“提升”方法,但C#从不使用它。忽略它。)

有关代表与活动之间差异的详情,请参阅my article on eventsalternate link)。

答案 1 :(得分:16)

通过使用事件关键字,您可以告知C#go generate隐藏方法, add_XXX remove_XXX 作为基础代理。这可以确保使用您的类的任何人只能附加和删除该事件的委托。关键点在于课堂上没有人提出这个事件,所以你可以完全控制何时会发生这种情况。

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

答案 2 :(得分: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);
    }
}