views:

179

answers:

4

I'd like a method that has the following API:

//get all users with a role of admin
var users = myRepository.GetUsers(u => u.Role == Role.Admin);

Will something like this work?

IList<User> GetUsers(Func<User, bool> predicate)
{            
  var users = GetAllUsers();
  return users.Where(predicate).ToList();                                                          
} 

If so, wil I be able to specify more complex predicates such as (pseudocode):

myRepository.GetUsers(u => u.CreatedDate is upto 14 days old);
+1  A: 

Yes, this will work.

What you're telling the compiler is that you're going to pass a function that works on a User object, and returns a bool - what the function looks like is entirely up to you. You can get pretty complex nesting stuff using ors (||) and ands (&&) too, but if it gets too hard to see what the predicate is doing, you should probably consider refactoring.

But basically any lambda that takes for example u as a User object, and turns it into an expression that returns bool will work.

Tomas Lycken
+8  A: 

That looks absolutely fine. However, if you want to use the predicate with something like LINQ to SQL, you'd want to use:

IList<User> GetUsers(Expression<Func<User, bool>> predicate)

That means the lambda expression will be converted into an expression tree instead of a delegate - and that expression tree can then be converted into SQL.

Jon Skeet
Really appreciate your response. Thanks
Ben Aston
+1  A: 

Looks fine to me!

James
+2  A: 

One tip: you can use Predicate<T> instead of Func<T, bool>, which is a little clearer (Predicate<T> is built in to .net 3.5, namespace System).

kronoz
`Predicate<T>` was actually in .NET 2.0, but `Func<T,bool>` tends to be used in LINQ - partly because some methods have `Func<T,int,bool>`.
Jon Skeet
Ah I forgot that it was in 2.0; could you give me a few examples of methods using Func<T, int, bool>? Thanks
kronoz