Last week I was doing some pair programming with Jason Olson and we were looking over a project I’m working on in connection with ASP.NET MVC and custom ControllerActionInvokers (more on this to come). As he was critiquing my code, he pointed out my usage of a Func<T, bool>, asking why I wasn’t using a Predicate<T>, which achieves the exact same thing, without having to redundantly specify the boolean return type (not to mention the semantic value it adds). My response: “Umm, because I forgot about that”.
Apparently when .NET 3.5 was released I fell in such deep love with the Func delegate that I completely gave up on ever using Predicate again, which seems pretty ridiculous. Obviously Func has many more forms than Predicate, and merits lots of usage, but blindly using it for everything would begin to demean its value. Luckily I didn’t forget about my beloved Comparison delegate, so you wouldn’t ever catch me using a Func<T1, T2, int> (where T1 and T2 where the same type) as opposed to a Comparison<T>.
After feeling a little pathetic, low-and-behold I began seeing instances all over the place of people doing the exact same thing I was doing. I’ve since stumbled upon three different open-source projects that have code using Func<T, bool> delegates instead of Predicate<T>. In addition, I remembered that ADO.NET Data Services implement their query interceptors as methods whose return type is Expression<Func<T, bool>>. Apparently I’m not the only person who has fallen victim to the forgotten delegate…
I’m by no means stating that using a Func<T, bool> as opposed to a Predicate<T> is bad or anything, I just found it somewhat interesting that Funcs have permeated code that would have otherwise used another delegate.
The reason why I do not use Predicate is that Linq doesn’t use it, so the following won’t compile:
Predicate IsPreferred;
Customer c = customers.Where(IsPreferred).SingleOrDefault();
“Where” expects Func and there is no way to convert one delegate to the other.
@Alex
That’s a good point, and just to clarify I was referring only to code that I’m developing from scratch. If an API you’re using requires a Func, then you have no choice.
LINQ uses Funcs because they’re very generic, which is exactly what you’d want in this case. A Func is only equivalent to a Predicate if TResult is a boolean, which leaves many other scenarios that merit the use of a Func .
With that said, I’m not really sure why some of the standard query operators in LINQ use Func instead of Predicate (i.e SkipWhile, TakeWhile, Where). I’d imagine it’s for consistency sake, since Funcs are leveraged throughout.
-Jonathan
too bad that void is not a first class citizen - otherwise you wouldnt need Action , you could just pass Funct