The Subject is Predicates: On the Use of Predicates in C#
by Chad Finsterwald
This code sample applies to ASP.NET in the .NET 2.0 framework. Examples are written in C#.
Contents
- Overview
- So What are Predicates?
- How do I Use Them?
- Performance
- As Long as We're Here: Actions and Converters
- Conclusion
Overview:
Like mathematicians, developers talk about their code in
aesthetic and sometimes hygienic terms. The code is “elegant,” or it
“looks clean,” and sometimes it
“smells bad”.
I have even heard developers refer to their code as “sexy.” Talking about your
code as sexy is surely a sign that you need to get out more!
Achieving elegant code is not easy and so as I deepen my experience
with .Net 2.0, I am always pleased to discover when the
framework offers a way to do something that I could have done in 1.1,
but can now do much more elegantly. Predicates and the related
Actions and Converters
are just such additions to the framework. They will not
revolutionize how you code, but used properly they will reduce the
amount of code needed, encourage reuse, and just look sexier.
This article will examine the following questions:
- What are
Predicates?
- How they are used?
- How does their performance stack up against similar
foreach routines?
- What are
Actions and Converters?
So What are Predicates?
A Predicate is a new class introduced by the .Net 2.0 framework.
The class has the following signature:
public delegate
bool Predicate (T obj) and
is used by collections such as List and Array
to perform methods like RemoveAll, Find, FindAll, Exists, etc.
Its signature reveals that a Predicate is a
Delegate.
What that means is that so long as the method signatures are
the same –i.e. the methods have the same return type and
accept the same arguments—then any method that conforms
to that signature can be called in its place. C# Delegates
have been compared to C or C++ function pointers, callback
functions, etc. They enable you to specify what the method that
you want to call looks like without having to specify, at compile
time, which actual method will be called.
Also revealed by its signature is that a Predicate
is a Generic method. There are a lot of good introductions to
Generics
so I will not traverse that ground here. Suffice it to
say in this context Generic refers to the fact that
the same Predicate can be used for Collections
with different Types.
One slight twist with
Predicates worth mentioning is that since the Predicate class is baked
into the .Net framework you do not need to specify the type argument
of the generic method or to create the delegate explicitly. Both of
these are determined by the compiler from the method arguments you supply. You
will see from the examples what this means in practice.
The chief benefit of using Predicates, besides the
“coolness factor,” is that they are more expressive, require less code,
promote reuse, and surprisingly, are faster than other alternatives. Using a Predicate turns out
to have better performance than a similar foreach operation.
This is demonstrated below.
How do I Use Them?
The best way to illustrate the use of Predicates is to
compare them to foreach routines. For example,
say you have a List collection like the one below. You want to find every member of
that collection that starts with “a”. One reasonable approach is
to use foreach and return a new List which contains only those
members of the original list that start with “a”.
The List collection below will be used
to illustrate the key concepts in this article.
To filter all members of this collection that begins with "a" using
forech, the method (or routine) would look something like this:
In this case the List collection
returned would contain the following items: Abel, Adam, and Anna.
Now what if instead of retrieving every member of the collection
that starts with “a” you just wanted to confirm that at
least one member of the collection started with an "a"? In this case you’d
likely create a new method like the one below. You might even be
clever and factor out the common code to evaluate if a
particular member of the collection started with “a” and use
that for both the Filter and Exists methods.
There is nothing particularly stinky about this approach and prior
to Predicates, this was the best way to achieve the desired result.
But let’s see how we could achieve the same ends using Predicates.
Using Predicates just smells better --at least to my refined olfactory
sensibility. The Predicate code could have also been written using an
Anonymous
Method. This is a good approach if the logic you are applying
to the collection is not going to be used again in the application.
If that logic might be reused, then my bias is to put it in a method
so you don’t run the risk of code duplication. I have also found
that Anonymous Methods decrease clarity as many beginning programmers
do not understand the syntax. So if you do use them, make sure everyone on
the team understands their use.
Sweet fancy Moses that is some elegant code!
Sure the results are not different than what was achieved using a foreach loop,
but using Predicates smells like it was just bathed in
rosewater, swaddled, and then pampered with frankincense and myrrh. (If you are like
me and wondered just what the f*#! are frankincense and myrrh, here's a
link.)
Scent aside, there is a limitation to the standard implementation
of Predicates. It is often the case that you will want to pass in a
parameter to the method which the Predicate points to. It would be
a pain to have to define a method for StartsWithA and another
method for StartsWithB, etc. Because Predicates are delegates,
however, you cannot change the signature to pass in additional
arguments. Fortunately, it is easy enough to wrap the predicate
in another class so you have access to additional parameters in your
predicate method. There is a good article by Alex Perepletov
entitled
“Passing
parameters to predicates” demonstrating this
technique.
Of course, I've only demonstrated a few of the methods
in the .Net framework that utilize predicates. I encourage
you to review the API for
Array and
List to view the other
methods of those classes that use Predicates. (I am not sure
if there are any other classes that have methods which use
Predicates, so if there are any outside of Array and List,
please let me know so that I can post them too.)
I would argue that even if the Predicate class is a little slower than
similar looping structures like foreach or for they are still
preferable as Predicates have other more important virtues.
I know there are performance Nazis out there who agonize over
nanosecond differences, but if a nanosecond difference is
that important to your application than it is likely you should
not be using C# at all. Still having an understanding of the performance
impact of your programming decisions is a good thing and
I was curious about how Predicates stacked up so I put together a simple
head-to-head comparison of Predicate vs. foreach.
The test compared a List of 100,000 string values to see which ones started with
"1." For each test iteration, the search was performed 100 times.
The results are below.

As you can see, Predicates are the winner.
We are, however, talking milliseconds
and, in most situations, nanoseconds so I would not take one approach
or the other on performance considerations alone.
Also a few days after I completed these tests, I found another article that conducts a
more through comparison between Predicates and foreach.
You can find that comparison
at Jon Skeet's Coding Blog.
As Long as We're Here: Actions and Converters
In addition to the Predicate class, .Net 2.0 also introduces
the Action and Converter classes.
Like Predicates, these are generic delegates.
The Action class provides a simple way to walk all items of a collection
and call a method on each member. Both Action and Converter
work in the same way as the Predicate
class --including the ability to either define or use Anonymous methods.
For example, if you wanted to display all the members of a List collection,
you could use the following:
The Converter class is used to change all members of a collection from one type
to another type. The signature of the Converter class
is a little different than the
Predicate or Action classes:
public List ConvertAll (Converter converter). It is, however,
used basically in the same way. For example, if I wanted to
turn a List collection of strings into a list collection of Names, (assuming for the
moment that I had created a Name class,) I could do the following.
I did not benchmark the Action or Converter
class, but my hunch is that they too would offer slight performance benefits over similar routines using
foreach. Like the Predicate class,
the chief benefit they offer is that they make it easier to write
the same elegant, sweet smelling code and will likely
encourage reuse as well. Finally, if you need to pass parameters to either class,
you can wrap them in another class as shown in the Predicate example cited earlier.
Conclusion:
So we have arrived at the end of the article. Likely at this point
you are so seduced by the sexiness of the code that the Predicate,
Action,
and Converter classes make possible that you are
contemplating leaving your significant other and
moving to Massachusetts to marry your application
--which is, I believe, legal here in Boston. I wish you both well in that endeavor!
As always, do not hesitate to email me if you have any questions (my email is in the
"About the Author" tab above.) If you extend what I've done or
have additional information I missed,
I would also greatly appreciate your letting me know. (Leaving a comment,
positive or incredibly positive, is also always appreciated.)