Sunday, September 02, 2007 12:00 AM
bart
Visual Basic 9.0 Feature Focus - Relaxed delegates
Welcome back to the Visual Basic 9.0 Feature Focus blog series. In this post, we'll cover Relaxed delegates, a small but useful feature that boosts developer convenience. In VB 8.0 the use of delegates was very strict concerning the methods supported to be called through a delegate. Two samples make this clear:
Delegate Sub Process(ByRef o As Object)
Module Module1
Sub DoIt(ByRef s As String)
Console.WriteLine(s)
End Sub
Sub Main()
Dim p As New Process(AddressOf DoIt)
p("Hello")
End Sub
End Module
Oops, this doesn't work. But why? The IDE and compiler complain about the following:
What's up? VB 8.0 has the nasty habit to require an exact signature match when pointing a delegate to a method. In the sample above, the compiler complains that the parameter to DoIt is a String while it expects an Object, even though each String is an Object because of the class hierarchy. In other words, regular rules that apply to regular method calls do not hold anymore when working with delegates: signatures have to match exactly. The same holds for the use of event handlers:
Class FrontEnd
Private WithEvents engine As MyEngine
Private Sub OnError(ByVal source As Object, ByVal e As ErrorEventArgs) Handles engine.OnError
End Sub
End Class
Class MyEngine
Public Event OnError As EventHandler(Of ErrorEventArgs)
Public Sub Fail()
RaiseEvent OnError(Me, New ErrorEventArgs("Bang!"))
End Sub
End Class
Class ErrorEventArgs
Inherits EventArgs
Private _message As String
Public ReadOnly Property Message() As String
Get
Return _message
End Get
End Property
Public Sub New(ByVal message As String)
_message = message
End Sub
End Class
The code above will compile but if you change the OnError method signature of the FrontEnd class like this:
Private Sub OnError(ByVal source As Object, ByVal e As EventArgs) Handles engine.OnError
it won't. See the difference? The 'e' parameter now is of type EventArgs rather than ErrorEventArgs and although the class hierarchy is there to make this a valid signature in regular method call circumstances, the compiler will nag about it:
The solution? VB 9.0! Both fragments above will compile now in VB 9.0 thanks to the concept of relaxed delegates. In other words, the method signature use in a delegate binding shouldn't be an exact match anymore, it should just be consistent with the rules that apply for regular method invocations. But there's more... If you don't need the arguments of the method being bound to the delegate, either using AddressOf or Handles, you can omit these:
Sub DoIt(ByRef s As String)
will be accepted for the following delegate:
Delegate Sub Process(ByRef o As Object)
and:
Private Sub OnError() Handles engine.OnError
will be accepted for this delegate:
EventHandler(Of ErrorEventArgs)
= Delegate Sub(ByVal sender As Object, ByVal e As ErrorEventArgs)
Happy coding!
Del.icio.us |
Digg It |
Technorati |
Blinklist |
Furl |
reddit |
DotNetKicks
Filed under: VB 9.0