Using C# 3.5 I wanted to build up a predicate to send to a where clause piece by piece. I have created a very simple Console Application to illustrate the solution that I a
When you use += or -= when delegate types, that just gives a call to Delegate.Combine
and Delegate.Remove
.
The important thing about multicast delegates is that the return value of all but the last executed delegate is ignored. They all get executed (unless an exception is thrown), but only the last return value is used.
For predicates, you might want to do something like:
public static Func And(params Func[] predicates)
{
return t => predicates.All(predicate => predicate(t));
}
public static Func Or(params Func[] predicates)
{
return t => predicates.Any(predicate => predicate(t));
}
You'd then do:
Func predicate = And(
t => t.Length > 10,
t => t.Length < 20);
EDIT: Here's a more general solution which is quite fun, if a bit bizarre...
public static Func Combine
(Func aggregator,
params Func[] delegates) {
// delegates[0] provides the initial value
return t => delegates.Skip(1).Aggregate(delegates[0](t), aggregator);
}
So you could then implement And as:
public static Func And(params Func[] predicates) {
return Combine((x, y) => x && y, predicates);
}
(I personally prefer this over using GetInvocationList()
, because you end up with a predicate you can pass to other bits of LINQ etc.)