Является ли ключевое слово "событие" необязательным в С#?

В чем разница между eventOne (с ключевым словом "событие" ) и eventTwo (w/o keyword)?

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

Ответы

Ответ 1

  • eventOne - это публичное событие, поддерживаемое частным полем типа EventHandler.
  • eventTwo - это общедоступное поле типа EventHandler.

В основном событие только инкапсулирует идеи "подписаться" и "отказаться от подписки" таким же образом, что свойство только инкапсулирует идеи "get" и "set", а не фактическое хранилище. (Что касается CLR, событие может также выставлять метод "raise", но С# никогда не использует его. Игнорируйте его.)

Смотрите мою статью о событиях (альтернативная ссылка) для получения дополнительной информации о различиях между делегатами и событиями.

Ответ 2

Используя ключевое слово event, вы указываете, что С# сгенерирует скрытые методы, add_XXX и remove_XXX для вашего основного делегата. Это гарантирует, что любой, кто использует ваш класс, может присоединять и удалять делегатов только для этого события. Ключевым моментом является то, что никто за пределами вашего класса и не возбуждает событие, поэтому вы получите полный контроль над тем, когда это произойдет.

Если вы не используете событие, вы просто открываете публичный делегат, который каждый может добавить, удалить и вызвать. Очень маловероятно, что вы хотите, чтобы кто-либо, кроме вашего класса, вызывал вызов.

Ответ 3

Это программа, иллюстрирующая разницу, с учетом ответов до

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