2010-02-05 20 views
8

me gustaría un método que tiene las siguientes API:C# método que acepta un predicado: ¿se ve bien?

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

Will algo así como este trabajo?

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

Si es así, yo wil ser capaz de especificar predicados más complejas, tales como (pseudocódigo):

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

¿Por qué no quieres devolver un número de usuarios de IEnumerable? –

+0

¿Es preferible un IEnumerable porque es más flexible? – Ben

+1

Un IList es un IEnumerable, por lo que un IEnumerable será menos flexible. Creo que el comentario puede haberse dirigido a la posible llamada innecesaria a ToList()? –

Respuesta

19

Eso se ve absolutamente bien. Sin embargo, si desea utilizar el predicado con algo como LINQ a SQL, que te gustaría utilizar:

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

Eso significa la expresión lambda se convertirán en un árbol de expresión en lugar de un delegado - y que la expresión árbol puede convertirse en SQL.

+0

Realmente aprecio su respuesta. Gracias – Ben

+2

+1 Esa explicación clarificó mi comprensión de LINQ en un dos por ciento. Muy agradecido. :) –

+0

Muchas gracias por esta respuesta. Estoy usando LINQ to SQL, y usar solo Func arroja una excepción OutOfMemory. Esto funciona perfecto – AngieM

3

Sí, esto va a funcionar.

Lo que le está diciendo al compilador es que va a pasar una función que funciona en un objeto User, y devuelve un bool - la apariencia de la función depende enteramente de usted. Puede obtener material de anidación bastante complejo utilizando ors (||) y ands (&&) también, pero si se vuelve demasiado difícil ver lo que está haciendo el predicado, probablemente debería considerar la refactorización.

Pero básicamente cualquier lambda que tome por ejemplo u como un objeto User y lo convierta en una expresión que devuelve bool funcionará.

2

Un consejo: se puede usar predicado <T> en lugar de Func < T, bool >, que es un poco más claro (predicado <T> está integrado en .NET 3.5, Sistema de espacio de nombres).

+2

'Predicado ' estaba realmente en .NET 2.0, pero 'Func ' tiende a ser utilizado en LINQ, en parte porque algunos métodos tienen 'Func '. –

+0

Ah, olvidé que estaba en 2.0; ¿podría darme algunos ejemplos de métodos usando Func ? Gracias – ljs

Cuestiones relacionadas