Является ли ключевое слово "событие" необязательным в С#?
В чем разница между 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);
}
}