Lambda Expressions with VB.Net June 25, 2009
Posted by fofo in VB 9.0, Visual Studio 2005, Visual Studio 2008.Tags: lambda expressions
trackback
Another idea-concept that is tightly linked with LINQ is LAMBDA expressions.
Lambda expressions are shorthand for anonymous delegates . Basically delegates allow you to create a variable that “points” to a method. We can use this variable at any time to invoke the method.
Lambdas are used extensively in LINQ queries, which are by nature pretty functional.
I will start talking a little bit about delegates and giving a short example on delegates before moving into lambda expressions.
You can start a Console application project with Visual Studio 2008/2010 (Express editions will also do) . Give your project a name and make sure VB is selected as the language of choice.
The first step when using a delegate is to define its signature. I am going to define a method signature for a function which is basically: its return type, the number of parameters it has, and the data type of each parameter.
Public Delegate Function FunctionForString(ByVal s As String) As Boolean
Now we can define a method that uses our new delegate as an input parameter. This particular method will accept a string array, and accept an instance of the delegate (some algorithm to perform on a string), then for each string in the array, it will apply the algorithm to it the return the array of strings back.
Public Function OperateStringArray(ByVal theStrings As String(), ByVal myFunction As FunctionForString) As String()
Dim myList As New List(Of String)
Dim mystring As StringFor Each mystring In theStrings
If myFunction(mystring) = True Then
myList.Add(mystring)
End IfNext
Return myList.ToArray()
End Function
The code above is very easy to understand. I just loop through the string array that has been passed in and I am going to perform myFunction(whatever has been passed in to the input parameter of type delagate) and perform it on each item in the string array, and if that is True, I will add it to a list. It is not confusing as it sounds. When you will run the code step by step it will make sense. Now I need to create a method that matches the delegation declaration.When this method will be passed as an argument to the OperateStringArray it becomes an instance of the delegate.
Public Function StringsFinishingWithS(ByVal s As String) As Boolean
Return s.EndsWith(“s”)
End Function
The method above matches the delegate declaration since it takes a string parameter and returns a Boolean result.
Basically it returns True if the string passed in, finishes with an “s”.
Now let’s write the code in our Main routine.
Sub Main()
Dim myStrings As String() = {“Davis”, “Jones”, “Beckett”, “Jordan”, “Kennt”}
Dim stringsA As String() = OperateStringArray(myStrings, AddressOf StringsFinishingWithS)
For Each s In stringsA
Console.WriteLine(s)
NextConsole.WriteLine(“Press enter to continue …”)
Console.ReadLine()End Sub
In this routine, I use our OperateStringArray, which knows how to loop through an array of strings (passed in as the the first parameter) and apply an algorithm to it (the method that encapsulates the algorithm is passed in as the second parameter).
Run you application. I suggest you use breakpoints and use F11 to execute step by step and see what is really happening.
The whole code in my Module1.vb module is
Module Module1
Public Delegate Function FunctionForString(ByVal s As String) As Boolean
Public Function OperateStringArray(ByVal theStrings As String(), ByVal myFunction As FunctionForString) As String()
Dim myList As New List(Of String)
Dim mystring As StringFor Each mystring In theStrings
If myFunction(mystring) = True Then
myList.Add(mystring)
End IfNext
Return myList.ToArray()
End Function
Public Function StringsFinishingWithS(ByVal s As String) As Boolean
Return s.EndsWith(“s”)
End FunctionSub Main()
Dim myStrings As String() = {“Davis”, “Jones”, “Beckett”, “Jordan”, “Kennt”}
Dim stringsA As String() = OperateStringArray(myStrings, AddressOf StringsFinishingWithS)
For Each s In stringsA
Console.WriteLine(s)
NextConsole.WriteLine(“Press enter to continue …”)
Console.ReadLine()End Sub
End Module
Let’s make some alterations in our code to incorporate the concept of Lambda expressions in it. By doing that we hope to have less and more elegant code. The purpose of Lambda expression is to be a shorthand for an anonymous delegate.
What I will do inside the Main() routine, is to remove the delagate and replace this bit of code
Dim stringsA As String() = OperateStringArray(myStrings, Function(s As String) s.StringsFinishingWithS(“s”))
with this
Dim stringsA As String() = OperateStringArray(myStrings, Function(s As String) s.EndsWith(“s”))
Our StringsFinishingWithS is gone now because we can use a lambda expression instead to perform the simple algorithm. I took the body of the StringsFinishingWithS method and in-lined it as the input parameter to OperateStringArray. I define the delegate’s method signature as:
Function (string S)
to match the OperateStringArray function type definition.
We could easily change our code above to work with generics and not just strings.
In order to change the delagate declaration to use generics we do this
Public Delegate Function FunctionGeneric(Of T)(ByVal s As T)
Our OperateStringArray becomes
Public Function OperateStringArray(ByVal theStrings As String(), ByVal myFunction As FunctionGeneric(Of String)) As String()
Dim myList As New List(Of String)
Dim mystring As StringFor Each mystring In theStrings
If myFunction(mystring) = True Then
myList.Add(mystring)
End IfNext
Return myList.ToArray()
End Function
We can use the Func instead of the delegate we defined. Func is a generic delegate which can be used by anyone.
Our function join given string and string, it returns a “string”.Now, I will dynamically assign the parameters and body of the function and name it join.
So If I comment everything out and just leave my Main() declaration, I have this chunk of code.
Dim join As Func(Of String, String, String) = Function(a, b) a & “ “ & b
Dim value As String = join(“nik”, “fofo”)
Console.WriteLine(value.ToString())
Console.ReadLine()
If you would like the source code just leave a comment and I will email it to you shortly afterwards.
Hope it helps!!!!












[...] this, let’s add another console application to our solution. Until VB 9.0 we had only inline lambda expressions. In VB 10.0 we have multiline lambdas. Consider the code below, we just have an array [...]
What is the VB equivalent for:
var a = new Action((x)=> Console.Writeline(x));
I tried this but it wants a return value.
Dim a as new Action(Of String)(Function(x) Console.WriteLine(x))