One thing that annoys me is that in a default Event, Sender is of type object and therefore almost always requires a manual cast before we can use it. Luckily since VB now also supports variance in delegates, we can update the signature of an event in such a way that the sender is strongly typed, see: Event parameter; "sender as Object", or "sender as T"?
Unfortunatly this doesn't work for existing declared events which senders are of type object.
Now one solution would be ofcourse to generate a fake EventHandler which internally takes care of the cast for you. I made a quick example, see:
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);
}
}
which can be used as you would expect it to be used:
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();
}
}
Now if I really want to use this, there is alot of work to be done. (The struct should behave just like the original delegate). Yet i do have the feeling that there is either already a great implementation out there, or there is no implementation since there are some major drawbacks i overlooked.
Who can answer me the above question? Any other hints?