multi-cast delegates and Predicate<T>

Fri, Aug 31, 2007 1-minute read

Since Predicate which is used for finding stuff in a generics list is in fact a multi-cast delegate, I thought it might be possible to chain several Predicates to simplify multiple requirements for the elements returned.

Consider the following code:

Predicate<int> greaterThan5 = delegate(int x) { return x > 5; };
Predicate<int> lessThan10 = delegate(int x) { return x < 10; };

It would be cool if it would be possible to chain them, by doing a simple:

Predicate<int> combined = lessThan10 + greaterThan5;

And then:

List<int> resulting = allInts.FindAll(combined);

Unfortunately it dosen’t work, or more precicely, it is only the last delegate that gets invoked.

It seems like MS did not envision people wanting to use multi-cast delegates for their predicates, and when looking at the List.FindAll implementation, its very clear, since it only invokes the delegate as it were a single cast one:

public List<T> FindAll(Predicate<T> match)
 {
    if (match == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
    }
    List<T> list = new List<T>();
    for (int i = 0; i < this._size; i++)
    {
        if (match(this._items[i]))
        {
            list.Add(this._items[i]);
        }
    }
    return list;
 }

So unfortunately you still need to do the old fashion way:

List<int> resulting = allInts.FindAll(lessThan10).FindAll(greaterThan5);

Lets hope they change it in c# 3.0