"Mo"

Who cares about predicates without closures?

Published on

Who cares about predicates without closures?

Authors

I’ve been using the System.Collections.Generic namespace an awful lot lately. I really like it, too. I use the List<T> collection all the time. It is so much better than inheriting from the CollectionBase to get a type-safe collection. I won’t go into the reasons here, though. This post is about Predicates. If you have a List<T> collection, you’ll notice it exposes a Find method that takes a Predicate as an argument. A Predicate is just a delegate that takes an object of type T and returns a boolean. When you call the Find method, it will call your Predicate for each object in its collection until your Predicate returns true. Looks like a nice, clean way to search collections, right?

Well, if you’re using C# anyway.

Compare the following VB.NET code and C# code:

VB.NET :

Module Module1
  Sub Main()
    Dim tests As New List(Of Test)
    tests.Add(New Test("test"))
    tests.Add(New Test("test2"))
    tests.Add(New Test("test3"))

    toSearchFor = "test2"
    Console.WriteLine(tests.Find(AddressOf FindTest).ID)
  End Sub

  Private toSearchFor As String = ""
    Private Function FindTest(ByVal val As Test) As Boolean
    Return val.ID = toSearchFor
  End Function

  Private Class Test
    Public ID As String
    Public Sub New(ByVal id As String)
      Me.ID = id
    End Sub
  End Class
End Module

C# :

using System;
using System.Collections.Generic;
using System.Text;

namespace CSPredicateExample
{
  class Program
  {
    static void Main(string[] args)
    {
      List<Test> tests = new List<Test>();
      tests.Add(new Test("test"));
      tests.Add(new Test("test2"));
      tests.Add(new Test("test3"));

      string toSearchFor = "test2";
      Console.WriteLine(tests.Find(delegate(Test val) { return val.ID == toSearchFor; }).ID);
    }

    class Test
    {
      public string ID;
      public Test(string id)
      {
        this.ID = id;
      }
    }
  }
}

Because of features like this, I am really looking forward to the next release of VB. Of course, with LINQ, will I even care about predicates then?

I would be very interested to know if anyone has any other suggestions on ways to effectively use the Predicate model in VB.

UPDATE: Wow, go Paul Stovell! Instead of complaining like I did, Paul actually did something to get around this limitation in the current version of VB.NET and created an implementation of “Almost-anonymous” methods! His method also shows how to use the Widening overloaded operator in VB.NET, which I haven’t seen much of. Cool!