2010-02-05 5 views
8

Vorrei un metodo che ha il seguente API:Metodo C# che accetta un predicato: sembra ok?

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

Will qualcosa di simile a questo lavoro?

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

Se è così, Wil io sia in grado di specificare predicati più complessi come (pseudocodice):

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

Perché non si desidera restituire un IEnumerable di utenti? –

+0

È preferibile un oggetto IEnumerable perché è più flessibile? – Ben

+1

Un IList è un IEnumerable, quindi un IEnumerable sarà meno flessibile. Penso che il commento potrebbe essere stato indirizzato verso la possibile chiamata non necessaria a ToList()? –

risposta

19

Sembra assolutamente soddisfacente. Tuttavia, se si desidera utilizzare il predicato con qualcosa di simile LINQ to SQL, che ci si vuole utilizzare:

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

Ciò significa che l'espressione lambda sarà convertito in un albero di espressione invece di un delegato - e che l'espressione l'albero può quindi essere convertito in SQL.

+0

Apprezzo davvero la tua risposta. Grazie – Ben

+2

+1 Questa spiegazione ha chiarito la mia comprensione di LINQ di un paio percentuale. Molto obbligato. :) –

+0

Grazie mille per questa risposta. Sto usando LINQ to SQL e l'utilizzo di Func genera un'eccezione OutOfMemory. Questo funziona perfettamente. – AngieM

3

Sì, questo funzionerà.

Quello che stai dicendo al compilatore è che stai per passare una funzione che funziona su un oggetto User e restituisce un bool - l'aspetto della funzione dipende interamente da te. È possibile ottenere materiale di nidificazione piuttosto complesso usando ors (||) e ands (&&), ma se diventa troppo difficile vedere cosa sta facendo il predicato, è consigliabile prendere in considerazione il refactoring.

Ma fondamentalmente qualsiasi lambda che prende ad esempio u come un oggetto User e lo trasforma in un'espressione che restituisce bool funzionerà.

2

Un consiglio: è possibile utilizzare predicato <T> invece di Func < T, bool >, che è un po 'più chiaro (predicato <T> è costruito in a Net 3.5, namespace System).

+2

'Predicato ' era in realtà in .NET 2.0, ma 'Func ' tende ad essere usato in LINQ - in parte perché alcuni metodi hanno 'Func '. –

+0

Ah ho dimenticato che era in 2.0; potresti darmi qualche esempio di metodi usando Func ? Grazie – ljs

Problemi correlati