arrow-left arrow-right brightness-2 chevron-left chevron-right circle-half-full dots-horizontal facebook-box facebook loader magnify menu-down RSS star Twitter twitter GitHub white-balance-sunny window-close
Passing parameters to delegates in VB.NET
2 min read

Passing parameters to delegates in VB.NET

This is an old post and doesn't necessarily reflect my current thinking on a topic, and some links or images may not work. The text is preserved here for posterity.

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

Enjoying these posts? Subscribe for more

Subscribe now
Already have an account? Sign in
Paul Stovell's Blog

Hello, I'm Paul Stovell

I'm a Brisbane-based software developer, and founder of Octopus Deploy, a DevOps automation software company. This is my personal blog where I write about my journey with Octopus and software development.

I write new blog posts about once a month. Subscribe and I'll send you an email when I publish something new.

Subscribe

Comments

You've successfully subscribed to Paul Stovell's Blog.
Success! Your account is fully activated, you now have access to all content.
Success! Your billing info is updated.