Earlier today I was wading through the code for the Microsoft Sync Services (many thanks to Lutz Roeder’s Reflector and the file disassembler addin) so that I could understand how it all pieces together. One of the interesting things I noticed was that in a couple of places they had appeared to write their own custom events which look a bit like:
public event EventHandler<ApplyChangeFailedEventArgs> ApplyChangeFailed
{
add
{
this.Events.AddHandler(DbServerSyncProvider.EventApplyChangeFailed, value);
}
remove
{
this.Events.RemoveHandler(DbServerSyncProvider.EventApplyChangeFailed, value);
}
}
Later in the code they then raise this event with the following untidy bit of code:
protected virtual void OnApplyChangeFailed(ApplyChangeFailedEventArgs value)
{
EventHandler<ApplyChangeFailedEventArgs> handler1 = (EventHandler<ApplyChangeFailedEventArgs>) this.Events[DbServerSyncProvider.EventApplyChangeFailed];
if (handler1 != null)
{
handler1(this, value);
}
}
This got me thinking about how this would be written in VB – thanks again to reflector I ended up with
Public Custom Event ApplyChangeFailed As EventHandler(Of ApplyChangeFailedEventArgs)
AddHandler(ByVal value As EventHandler(Of ApplyChangeFailedEventArgs))
Me.Events.AddHandler(EventApplyChangeFailed, value)
End AddHandler
RemoveHandler(ByVal value As EventHandler(Of ApplyChangeFailedEventArgs))
Me.Events.RemoveHandler(EventApplyChangeFailed, value)
End RemoveHandler
RaiseEvent(ByVal sender As Object, ByVal e As ApplyChangeFailedEventArgs)
Dim handler1 As EventHandler(Of ApplyChangeFailedEventArgs) = TryCast(Me.Events.Item(EventApplyChangeFailed), EventHandler(Of ApplyChangeFailedEventArgs))
If (Not handler1 Is Nothing) Then
handler1.Invoke(sender, e)
End If
End RaiseEvent
End Event
Ok, so that’s the event declaration – you will notice that most of the code to do with raising the event has now been moved into the RaiseEvent part of the custom event. Now when we raise the event we just do:
Protected Overridable Sub OnApplyChangeFailed(ByVal value As ApplyChangeFailedEventArgs)
RaiseEvent ApplyChangeFailed(Me, value)
End Sub
I think you would agree this is much tidier from a consumer point of view!