github.com/fsharp/fslang-suggestions/issues/162

больше о стандартной модели событий в .NET, я обнаружил, что перед введением обобщений в C # метод, который будет обрабатывать событие, представлен этим типом делегата:

//
// Summary:
//     Represents the method that will handle an event that has no event data.
//
// Parameters:
//   sender:
//     The source of the event.
//
//   e:
//     An object that contains no event data.
public delegate void EventHandler(object sender, EventArgs e);

Но после того, как дженерики были введены в C # 2, я думаю, что этот тип делегата был переписан с использованием дженериков:

//
// Summary:
//     Represents the method that will handle an event when the event provides data.
//
// Parameters:
//   sender:
//     The source of the event.
//
//   e:
//     An object that contains the event data.
//
// Type parameters:
//   TEventArgs:
//     The type of the event data generated by the event.
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);

У меня есть два вопроса здесь:

Во-первых, почему не былоTEventArgs параметр типа сделалконтравариантный ?

Если я не ошибаюсь, рекомендуется сделать параметры типа, которые отображаются как формальные параметры в сигнатуре делегата, контравариантными, а параметр типа, который будет возвращаемым типом в коварианте сигнатуры делегата.

В книге Джозефа Албахари, C # в двух словах, я цитирую:

Если вы определяете общий тип делегата, рекомендуется:

Отметьте параметр типа, используемый только в возвращаемом значении, как ковариантный (out).Отметьте любые типы параметров, используемые только для параметров, как контравариантные (в).

Это позволяет преобразованиям работать естественным образом, уважая отношения наследования между типами.

Второй вопрос: почему не было общего ограничения для обеспечения того, что TEventArgs наследуются отSystem.EventArgs?

Следующее:

public delegate void EventHandler<TEventArgs>  (object source, TEventArgs e) where TEventArgs : EventArgs; 

Заранее спасибо.

Отредактировано для уточнения второго вопроса:

Кажется, что общее ограничение на TEventArgs (где TEventArgs: EventArgs) была там раньше и была удалена Microsoft, так что, похоже, команда разработчиков поняла, что это не имеет большого практического смысла.

Я отредактировал свой ответ, включив в него некоторые скриншоты из

Справочный источник .NET

Ответы на вопрос(1)

Ваш ответ на вопрос