VB finally gets improved lambda support

Published on July 11, 2010 by Toran Billups

Last year I was working with Visual Basic a great deal and found the lambda support to be only half baked. For instance if you wrote a lambda expression it required that the expression return a value. But if you wanted to write something for a simple sub routine that had no return value, you had to write some very confusing code to workaround this language limitation.

For example, in the test method below I'm using Rhino Mocks to prove a method called SaveUser was called during the controller action. But because this SaveUser method isn't a function that returns a value I had to instead create a wrapper function that returned nothing (as object).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 
<TestClass()> _
Public Class UserControllerTest
 
    <TestMethod()> _
    Public Sub Should_UpdateModel_And_Call_Save_When_ID_Provided_To_The_Controller_Returns_A_Valid_User()
        Dim Service As IUserService = MockRepository.GenerateStub(Of IUserService)()
        Dim Controller As UserController = New UserController(Service)
 
        Dim User = New User()
 
        Service.Stub(Function(x) x.GetUserById(1)).[Return](User)
 
        Dim GetResult As ViewResult = Controller.Edit(1, Nothing)
 
        Dim GetModel As User = DirectCast(GetResult.ViewData.Model, User)
 
        Service.AssertWasCalled(Function(x) Wrap_SaveUser(x, User))
    End Sub
	
    Function Wrap_SaveUser(ByVal Service As IUserService, ByVal User As User) As Object
        Service.SaveUser(User)
 
        Return Nothing
    End Function
 
End Class

But with the latest compiler improvements you no longer need to write this confusing code. And assuming you have Visual Studio 2010 installed, this trick works for both dotnet 3.5 and 4.0!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
<TestClass()> _
Public Class UserControllerTest
 
    <TestMethod()> _
    Public Sub Should_UpdateModel_And_Call_Save_When_ID_Provided_To_The_Controller_Returns_A_Valid_User()
        Dim Service As IUserService = MockRepository.GenerateStub(Of IUserService)()
        Dim Controller As UserController = New UserController(Service)
 
        Dim User = New User()
 
        Service.Stub(Function(x) x.GetUserById(1)).[Return](User)
 
        Dim GetResult As ViewResult = Controller.Edit(1, Nothing)
 
        Dim GetModel As User = DirectCast(GetResult.ViewData.Model, User)
 
        Service.AssertWasCalled(Sub(x) x.SaveUser(User))
    End Sub
 
End Class

I wanted to highlight this because I found the workaround above to be very painful in previous versions of VB. Now that is some coevolution that I can get excited about!