jump to navigation

Lambda Expressions with VB.Net June 25, 2009

Posted by fofo in VB 9.0, Visual Studio 2005, Visual Studio 2008.
Tags:
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 String

For Each mystring In theStrings

If myFunction(mystring) = True Then
myList.Add(mystring)
End If

Next

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)
Next

Console.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 String

For Each mystring In theStrings

If myFunction(mystring) = True Then
myList.Add(mystring)
End If

Next

Return myList.ToArray()

End Function

Public Function StringsFinishingWithS(ByVal s As String) As Boolean
Return s.EndsWith(“s”)
End Function

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)
Next

Console.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 String

For Each mystring In theStrings

If myFunction(mystring) = True Then
myList.Add(mystring)
End If

Next

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!!!!

Add to FacebookAdd to NewsvineAdd to DiggAdd to Del.icio.usAdd to StumbleuponAdd to RedditAdd to BlinklistAdd to Ma.gnoliaAdd to TechnoratiAdd to Furl

Comments»

1. VB 10.0 new features and Visual Studio 2010 « DOT NET RULES - June 27, 2009

[…] 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 […]

2. Mark - August 3, 2009

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))


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: