Я считаю, что должно быть много вопросов по SO, связанных с этим, но я не могу придумать подходящие ключевые слова для их поиска.
Код
class Subscriber
{
public Subscriber(Notifier n)
{
n.OnSomeEvent += (object sender, EventArgs e) => { }; //This does not compile
n.OnSomeEvent += ReactOnEvent; //This compile successfully!
}
private void ReactOnEvent(object sender, EventArgs e)
{
}
}
class Notifier
{
public event EventHandler<MyEventArgs> OnSomeEvent;
public void Trigger()
{
OnSomeEvent?.Invoke(this, new MyEventArgs());
}
}
class MyEventArgs : EventArgs
{
}
Ошибки компиляции для регистрации лямбда-выражения имеют смысл.
Ошибка CS1661 Не удается преобразовать лямбда-выражение в тип делегата «EventHandler‹MyEventArgs>», поскольку типы параметров не соответствуют типам параметров делегата.
Ошибка CS1678 Параметр 2 объявлен как тип «System.EventArgs», но должен быть «ConsoleApplication1.MyEventArgs».
Но почему компилятор не дает мне те же ошибки для этого? Является ли мое понимание обработки событий в корне неверным? Я думаю, что компилятор требует, чтобы сигнатура события и его обработчиков совпадали.
n.OnSomeEvent += ReactOnEvent;
Изменить: ответ на этот вопрос
Как указал Питер в своих комментариях и процитировал ms docs,
(начиная с .NET 3.5)... вы можете назначать делегатам не только методы с совпадающими сигнатурами, но и методы, которые возвращают больше производных типов (ковариация) или принимают параметры, которые имеют меньше производных типов (контравариантность), чем указано в тип делегата.