Using methods that get passed (Generic) delegates

I recently saw this question regarding the use of methods that get passed delegates – specifically, the .NET 2 collection classes make use of this, like for example the List<T> class, which takes a Predicate<T> as a parameter to its Find method.

Now the question is how to make use of this method? How does the delegate know what to do when it’s called? As I see it, there are two (good) approaches to this: using an anonymous method and using a separate class. I’m going to illustrate both approaches below, with a sample that makes a few assumptions:

  • You have a class called MyObject that has a property called Id, of type Guid.
  • You have a list of MyObject instances, declared List<MyObject> list = new ..., which contains a few instances.
  • Now you want to write a method called FindById, that takes a Guid and makes use of the method List<T>.Find to find a MyObject in the list which has the given Id.
Anonymous methods

I’m not going to explain the complete concept of anonymous methods in this article. Suffice it to say that they can be used in places where delegates would otherwise be expected in .NET, but without the overhead of having to create a named method to pass in to the delegate’s constructor.

Using an anonymous method, you could write your FindById method like this:

MyObject FindById(Guid searchId) {
  return list.Find(delegate(MyObject myObject) {
    return myObject.Id == searchId;
  });
}

As you can see, an anonymous method is created that has the exact signature of the Predicate<T> delegate, getting passed a MyObject and returning a bool. This anonymous method has direct access to the searchId that was passed in to FindById, so a comparison is easily possible.

A separate class

The worst drawback of the anonymous method approach is that it’s not easily reusable. If you need a similar comparison algorithm in another place, you’ll have to write the complete code again. This may not be a problem in the sample, but if the code were a bit more complex it wouldn’t be a good idea. So why am I talking about a separate class? Because the value that’s needed for the comparison needs to be stored somewhere, and this shouldn’t be done in the same class that defines the FindById method – it’s much cleaner (and easier to make thread-safe) to put the value into a separate class. Of course, this class could be within the other, so it won’t polute your namespace. So the code for that extra class and the FindById method could look like this:

class MySearchByIdClass {
  Guid searchId;
  public MySearchByIdClass(Guid searchId) {
    this.searchId = searchId;
  }

  public bool PredicateDelegate(MyObject myObject) {
    return myObject == searchId;
  }
}

MyObject FindById(Guid searchId) {
  return list.Find(new Predicate<MyObject>(
    new MySearchByIdClass(searchId).PredicateDelegate));
}

Obviously the coding overhead is a bit higher here, but then we get complete reusability in return. The FindById method simply creates an instance of the encapsulation class to store the search parameter and uses that class’s delegate implementation to pass in to the Find method.

1 Comment on Using methods that get passed (Generic) delegates

  1. Thanks. Usefull and clear.

    Like

Leave a Comment

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