Generic Delegates and Lambda Expressions


Archimedes said: "Give me a place to stand and a lever long enough and I will move the world." Archimedes was referring to the potential power of tools to magnify the amount of work that can be done. Generic delegates and Lambda Expressions are tools. These tools magnify the amount of work you can do with less code.

In this article, you will explore generic delegates, the ForEach(Of T) generic method, and Lambda Expressions for VB9. Besides the ForEach(Of T) method, you'll look at the Action, Func, and Predicate anonymous delegates.

A Quick Review of Lambda Expressions

When you hear someone talk about functional programming, they are referring to Lambda Expressions. Lambda Expressions have been in other languages for a while and they are based on 70 year old mathematics, Lambda Expressions.

For your purposes, Lambda Expressions are basically inline functions that are used where historically you would have used delegates. You use Lambda Expressions instead because of their concise nature they fit in more naturally with LINQ and other new .NET technologies. A Lambda Expression is comprised of the keyword Function, a parameter list, and is immediately followed by the statement or expression that makes up the body of the function.

In VB9, Lambda Expressions begin with Function and have n-number of arguments. If the types can be inferred, the argument need not be provided explicitly. If the type cannot be inferred or Option Strict On is set, the type (As Type) must be provided for the arguments. Immediately following the Function(arg1, arg2, ..., argn) part of the expression, you need to supply the expression. The expression must return a result. You'll see some Lambda Expressions in the code samples.

The generic delegate Action(Of T) is a rough implementation of the Command behavior pattern. To use Action(Of T), declare a variable of type Action(Of T) and specify the type for T; for example, Integer. Then, initialize the Action object with the address of a delegate that accepts the number and type of arguments expressed in the Action declaration. (You can provide more than one argument for Action.) Listing 1 demonstrates how to use Action with a single argument.

Listing 1: Declaring and initializing an instance of Action(Of T) where T is expressed as an Integer and it is assigned to the address of a subroutine, Print.

Sub DemoActionOfT()
   ' Can't use Lambda here (can in C#) because VB Lambdas
   ' have a return value
   Dim Action As Action(Of String) = AddressOf Print
   Action("Hello World")
End Sub

Sub Print(ByVal str As String)
End Sub

In VB9, you can't initialize an Action object with a Lambda Expression because Lambda Expressions in VB9 are designed around expressions—code that has a return value—not statements—or, lines of code that yield no return value.

Easy Iteration with Array.ForEach(Of T)

ForEach(Of T) performs a specified action over an array of items where T indicates the type of the item. The first argument to ForEach is the array and the second arguments is the delegate of an instance of Action(Of T). Listing 2 demonstrates how to use ForEach. The array is represented by the anonymous type declaration of numbers and the Action(Of T) object is represented by the AddressOf Print.

Listing 2: Demonstrates the ForEach generic method that iterates over an array of items and performs the operation expressed by the Action delegate.

Sub DemoForEach()
   Dim numbers() = {1, 2, 3, 4, 5}

   Array.ForEach(numbers, AddressOf Print)

End Sub

Sub Print(ByVal str As String)
End Sub

Capturing Behaviors with Func(Of T)

The generic delegate Func(Of T) is designed to accept n-arguments—parameterized types—and the nth (or last argument) is the return type. For example, Func(Of Integer, Integer, Integer) means that the generic delegate accepts three integers and returns an integer. Because Func has a return argument, it can be initialized with a Lambda Expression. Listing 3 demonstrates a Lambda Expression that is assigned to an instance of Func(Of Integer, Integer, Integer) where the behavior performs simple arithmetic.

Listing 3: A Lambda Expression that accepts to arguments assigned to an instance of Func(Of T, T, T).

Sub DemoFunctionOfT()

   ' Argument 1, 2, n and result, the last argument
   Dim Adder As Func(Of Integer, Integer, Integer) = _
   Function(x, y) x + y

   Console.WriteLine(Adder(4, 5))
End Sub

Implementing Comparison Behaviors with Predicate(Of T)

The Predicate delegate is designed to accept arguments and return a Boolean. Its intended use is to accept test parameters and return a Boolean indicating the Boolean result of the test. In the example in Listing 4, the code tests the length of the input string to determine whether it is five characters in length.

Listing 4: The Predicate generic delegate demonstrates how to capture a test with a Boolean result.

Sub DemoPredicateOfT()
   ' Can use Lambda because predicate has return of Boolean
   Dim pred As Predicate(Of String) = _
   Function(str) str.Length = 5

   Console.WriteLine("'Hello' is five characters long is {0}", _
End Sub

Although you aren't required to assign Lambda Expressions to generic delegates, sometimes using the generic delegates make the code clearer and generic delegates are a convenient means of reusing lambda Expressions (or delegates, as is the case with Action) or even passing them around to functions.


Lambda Expressions in VB9 start with the Function keyword and parameters. The body of the Lambda Expression (in VB9) is an expression, aka code that yields a result. Lambda Expressions can be used directly or assigned to the generic delegates like Predicate and Func. Having these convenient storage types for Lambda Expressions makes it easier to reuse Lambda Expressions and pass them as arguments.

Remember that Lambda Expressions are basically shorthand for delegates. You can use Lambda Expressions anywhere you would use a regular delegate. The key benefit is that Lambda Expressions are more concise and consequently fit nicely with new code added to the .NET framework to support LINQ (Language Integrated Query).

About the Author

Paul Kimmel is the VB Today columnist for and has written several books on object-oriented programming and .NET. Check out his upcoming book LINQ Unleashed for C# due in Spring 2008. You may contact him for technology questions at

If you are interested in joining or sponsoring a .NET Users Group, check out Glugnet opened a users group branch in Flint, Michigan in August 2007. If you are interested in attending, check out the web site for updates.

Copyright © 2007 by Paul T. Kimmel. All Rights Reserved.


  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Complex hybrid environments can make it difficult to track interdependencies, increasing the risk of disrupting critical business services. In this white paper by EMA, you'll learn how application discovery and dependency mapping can help you: Meet granular targets for availability, cost, and time-to-revenue for cloud services. Accelerate mean time to repair (MTTR) while communicating better with stakeholders. Manage even the most complex hybrid environments more efficiently and effectively Understand the …

  • Improving traffic management can deliver big benefits, especially across a global infrastructure. Read this Brocade white paper to see how virtualizing traffic management helps you improve business continuity and transform the customer experience--without the cost and management overhead of additional hardware.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date