Passing parameters to delegates in VB.NET

In C# we have anonymous methods. You can read about them and how they are implemented in this post on Raymond Chens blog:

http://blogs.msdn.com/oldnewthing/archive/2006/08/02/686456.aspx

One of the features of anonymous methods is they allow you to use variables that would normally be out of scope. Raymond explains that this works by generating a class under the hood, populating it with the variables and then passing the method. Here is an example of what C# can do:

public void Main() 
{
    var developers = new List<string>(new []  { "Woody Allen", "Bill Gates" } );

    var greatDeveloperFirstName = "Bill";

    var greatDevelopers = developers.FindAll(
        delegate (string developerName) {
            // Note that I am using a variable that would be "out of scope" if 
            // this wasn't an anonymous method:
            return developerName.StartsWith(greatDeveloperFirstName);
        });
}

In VB.NET, since you can't do anonymous methods, it also makes it hard to pass arguments to methods that expect a Predicate<T> (such as List<T>.FindAll()).

Here's a VB.NET class that you can reuse to "wrap" a Predicate<T> in order to pass arguments to it.

Public Delegate Function PredicateWrapperDelegate(Of T, A) _
    (ByVal item As T, ByVal argument As A) As Boolean

Public Class PredicateWrapper(Of T, A)
    Private _argument As A
    Private _wrapperDelegate As PredicateWrapperDelegate(Of T, A)

    Public Sub New(ByVal argument As A, _ 
        ByVal wrapperDelegate As PredicateWrapperDelegate(Of T, A))

        _argument = argument
        _wrapperDelegate = wrapperDelegate
    End Sub

    Private Function InnerPredicate(ByVal item As T) As Boolean
        Return _wrapperDelegate(item, _argument)
    End Function

    Public Shared Widening Operator CType( _
        ByVal wrapper As PredicateWrapper(Of T, A)) _
        As Predicate(Of T)

        Return New Predicate(Of T)(AddressOf wrapper.InnerPredicate)
    End Operator

End Class

To use this class in your VB.NET code:

Sub Main()

    Dim developers As New List(Of String)
    developers.Add("Paul Stovell")
    developers.Add("Bill Gates")

    Dim greatDeveloperFirstName as string = "Paul" 

    Dim greatDevelopers As List(Of String) = developers.FindAll(_ 
        New PredicateWrapper(Of String, String)(  _
            greatDeveloperFirstName, _
            AddressOf IsGreatDeveloper))

    For Each greatDeveloper As String In greatDevelopers
        Console.WriteLine(greatDeveloper)
    Next

    Console.ReadKey()

End Sub

Note that you can now pass arguments to your "FindAll" predicate :)

Function IsGreatDeveloper(ByVal item As String, ByVal argument As String) As Boolean        
    Return item.StartsWith(argument)
End Function
vb.net
Posted by: Paul Stovell
Last revised: 04 Feb, 2012 04:03 AM History

Trackbacks

Comments

sobeloscehync
sobeloscehync
08 Nov, 2009 03:51 AM

Absolument, il est droit http://www.gnduonline.org le viagra

etiennexxx9
etiennexxx9
19 Nov, 2009 04:55 AM

It is possible since Visual Basic 2008 and known as Lambda Expressions.

You can use it as follow:

Sub Main()

Dim developers As New List(Of String)({"Paul Stovell", "Bill Gates"})

Dim greatDeveloperFirstName as string = "Paul" 

Dim greatDevelopers As List(Of String) = developers.FindAll( _
    Function(developerName As String) _
        developerName.StartsWith(greatDeveloperFirstName))

End Sub
Draickadakarf
Draickadakarf
30 Oct, 2010 10:24 AM

It takes me a week to establish my barely website . It looks heinous and insufficient so i emergency your recommendation to amend it. Valid post your suggestion here. Thanks a lot.

sastflify
sastflify
31 Oct, 2010 10:57 AM

Boy, I am searching the internet and come up with some elevated communications position as forums, blogs. Could you surrender me some suggestion?

Bicsearia
Bicsearia
22 Nov, 2010 06:44 AM

I stand in want to enquire of you how desire a day do surf internet a day? And what are you doing? Working, chating, searching inexperienced information? And what your favorite site?

No new comments are allowed on this post.