One of the nice new features in Visual Basic 9 are lambda expressions. They where actually added as one of the underlying pieces for LINQ. But besides enabling LINQ you can use them in all sorts of places. One of the places they really help me is in places where I previously needed to declare a delegate and use that.
Take for example the following code where I use the ThreadPool to do some work:
Private Sub btnStart_Click() Handles btnStart.Click ThreadPool.QueueUserWorkItem(AddressOf DoWork) End Sub Private Sub DoWork(ByVal state As Object) For index As Integer = 1 To 100 SetProgressLabel(index) Thread.Sleep(100) Next End Sub
The SetProgressLabel function reports the progress to the user by setting the text on a label. As the work is done in a background thread I need to use Invoke to set the text property.
Before VB9 I would have to implement the SetProgressLabel like this:
Delegate Sub SetProgressLabelDelegate(ByVal percentage As Integer) Private Sub SetProgressLabel(ByVal percentage As Integer) If lblStatus.InvokeRequired Then lblStatus.Invoke( _ New SetProgressLabelDelegate( _ AddressOf SetProgressLabel), _ percentage) Else lblStatus.Text = percentage.ToString() + " %" End If End Sub
First I would need to declare a delegate with the right signature, create an object passing in the address of the function to call and the parameters. Even though I declared the delegate with its parameters the Invoke is not aware of these and I can add make errors with the parameters which don’t show until runtime.
So here is a better way to do this in VB9:
Private Function SetProgressLabel(ByVal percentage As Integer) As Object If lblStatus.InvokeRequired Then lblStatus.Invoke(Function() SetProgressLabel(percentage)) Else lblStatus.Text = percentage.ToString() + " %" End If Return Nothing End Function
This time I use an lambda expression to call the SetProgressLabel function. No need for the extra delegate and I get full compile time checking [:)]. In fact the only drawback is that I need to declare SetProgressLabel as a function instead of a sub as VB forces a lambda expression to return a value. This makes working with lambda expressions somewhat less powerful than the C# implementation [:(] Lets just hope that problem is rectified soon.
One neat thing is that you don’t actually need to target the 3.5 framework to use lambda expressions. The previous sample works just fine targeting the .NET 2.0 runtime as long as VB9 is used. The reason for this is that the lambda expression syntax is actually just a compiler trick and it creates an delegate for us behind the scenes. Pretty cool!