Одна вещь, которая меня раздражает, это то, что в событии по умолчанию Sender имеет тип объекта и поэтому почти всегда требует ручного приведения, прежде чем мы сможем его использовать.К счастью, поскольку VB теперь также поддерживает дисперсию в делегатах, мы можем обновить сигнатуру события таким образом, чтобы отправитель строго типизирован, см .: Параметр события;«отправитель как объект» или «отправитель как T»?
К сожалению, это не работает для существующих объявленных событий, отправители которых имеют тип объекта.
Теперь одно решение будетКонечно, чтобы создать поддельный EventHandler, который внутренне заботится о актерах для вас.Я сделал быстрый пример, см .:
struct EventHandler<TSender, TEventArgs>
where TEventArgs: EventArgs
{
private readonly Action<TSender, TEventArgs> _delegate;
public EventHandler(Action<TSender, TEventArgs> @delegate)
{
if (@delegate == null)
throw new ArgumentNullException("@delegate");
_delegate = @delegate;
}
public static implicit operator EventHandler<TEventArgs>(EventHandler<TSender, TEventArgs> eventHandler)
{
return new EventHandler<TEventArgs>(eventHandler.Execute);
}
private void Execute(object sender, EventArgs e)
{
TSender typedSender = (TSender)sender;
TEventArgs typedEventArgs = (TEventArgs)e;
_delegate(typedSender, typedEventArgs);
}
}
, который можно использовать так, как вы ожидаете, что он будет использоваться:
class Program
{
event EventHandler<EventArgs> Test;
static void Main(string[] args)
{
new Program().Main();
}
void Main()
{
Test += new EventHandler<Program, EventArgs>(TestEventHandler);
Test(this, EventArgs.Empty);
}
void TestEventHandler(Program sender, EventArgs e)
{
throw new NotImplementedException();
}
}
Теперь, если я действительно хочу это использовать, естьмного работы предстоит сделать.(Структура должна вести себя так же, как исходный делегат).Тем не менее, у меня есть ощущение, что либо уже есть отличная реализация, либо ее нет, поскольку есть некоторые серьезные недостатки, которые я упустил из виду.
Кто может ответить на мой вопрос выше?Любые другие советы?