9

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);
Ben Aston
  • 53,718
  • 65
  • 205
  • 331

3 Answers3

20

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
  • 1,421,763
  • 867
  • 9,128
  • 9,194
3

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 Aschan
  • 58,548
  • 56
  • 243
  • 402
2

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).

ljs
  • 37,275
  • 36
  • 106
  • 124
  • 2
    `Predicate` was actually in .NET 2.0, but `Func` tends to be used in LINQ - partly because some methods have `Func`. – Jon Skeet Feb 05 '10 at 12:01
  • Ah I forgot that it was in 2.0; could you give me a few examples of methods using Func? Thanks – ljs Feb 05 '10 at 13:45