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, так что, похоже, команда разработчиков поняла, что это не имеет большого практического смысла.
Я отредактировал свой ответ, включив в него некоторые скриншоты из