2010-02-05 4 views
8

würde ich eine Methode, wie das die folgende API hat:C# -Methode akzeptiert ein Prädikat - sieht das gut aus?

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

Will etwas wie diese Arbeit?

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

Wenn ja, wil ich in der Lage sein, komplexere Prädikate angeben, wie (Pseudo-Code):

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

Warum möchten Sie keine IEnumerable von Benutzern zurückgeben? –

+0

Ist IEnumerable vorzuziehen, weil es flexibler ist? – Ben

+1

Ein IList ist ein IEnumerable, ein IEnumerable wird also weniger flexibel sein. Ich denke, der Kommentar wurde vielleicht auf den möglicherweise unnötigen Aufruf von ToList() gerichtet? –

Antwort

19

Das sieht absolut gut aus. Wenn Sie jedoch das Prädikat mit so etwas wie LINQ to SQL verwenden möchten, dann würden Sie verwenden möchten:

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

, dass die Lambda-Ausdruck bedeutet, wird in einen Ausdrucksbaum anstelle eines Delegierten umgewandelt werden - und dieser Ausdruck Baum kann dann in SQL konvertiert werden.

+0

Wirklich zu schätzen Ihre Antwort. Danke – Ben

+2

+1 Diese Erklärung verdeutlicht mein Verständnis von LINQ um ein paar Prozent. Herzlichen Dank. :) –

+0

Vielen Dank für diese Antwort. Ich verwende LINQ to SQL, und die Verwendung nur von Func löst eine OutOfMemory-Ausnahme aus. Das funktioniert perfekt. – AngieM

3

Ja, das funktioniert.

Was Sie den Compiler sagen, ist, dass Sie eine Funktion übergeben werden, die auf einem User-Objekt funktioniert, und gibt bool zurück - wie die Funktion aussieht, liegt ganz bei Ihnen. Sie können ziemlich komplexe Verschachtelungstypen mit ors (||) und ands (&&) auch erhalten, aber wenn es zu schwer wird zu sehen, was das Prädikat tut, sollten Sie wahrscheinlich Refactoring in Betracht ziehen.

Aber im Grunde jedes Lambda, das zum Beispiel u als User Objekt nimmt, und verwandelt es in einen Ausdruck, der bool zurückgibt.

2

Ein Tipp: Sie können Prädikat verwenden <T> statt Func < T, bool >, die ein wenig klarer ist (Prädikat <T> eingebaut ist 3,5 bis .net, Namespace-System).

+2

'Prädikat ' war eigentlich in .NET 2.0, aber 'Func ' neigt dazu, in LINQ verwendet werden - teilweise weil einige Methoden 'Func ' haben. –

+0

Ah ich habe vergessen, dass es in 2.0 war; Könnten Sie mir ein paar Beispiele für Methoden geben, die Func verwenden? Vielen Dank – ljs

Verwandte Themen