2009-08-01 22 views
42

Mam metodę, która akceptuje Expression<Func<T, bool>> jako parametr. Chciałbym użyć go jako predykatu w metodzie List.Find(), ale nie mogę go przekonwertować na predykat, który przyjmuje lista. Czy znasz prosty sposób na zrobienie tego?Jak przekonwertować wyrażenie <Func <T, bool>> na predykat <T>

public IList<T> Find<T>(Expression<Func<T, bool>> expression) where T : class, new() 
{ 
    var list = GetList<T>(); 

    var predicate = [what goes here to convert expression?]; 

    return list.Find(predicate); 
} 

Aktualizacja

Łącząc odpowiedzi od tvanfosson i 280Z28, jestem teraz za pomocą to:

public IList<T> Find<T>(Expression<Func<T, bool>> expression) where T : class, new() 
{ 
    var list = GetList<T>(); 

    return list.Where(expression.Compile()).ToList(); 
} 

Odpowiedz

46
Func<T, bool> func = expression.Compile(); 
Predicate<T> pred = t => func(t); 

Edycja: na komentarze mamy lepszą odpowiedź na sekundę linia:

Predicate<T> pred = func.Invoke; 
+0

Perfect! Dzięki! –

+7

Lub: pred = func.Invoke; –

+0

Tak, func.Invoke wygląda lepiej. –

25

Nie widzę potrzeby stosowania tej metody. Po prostu użyj Where().

var sublist = list.Where(expression.Compile()).ToList(); 

Albo jeszcze lepiej zdefiniować wyrażenie jako inline lambda.

var sublist = list.Where(l => l.ID == id).ToList(); 
+1

Heh, to prawda. To właśnie dostaję dla wąskiej lektury. –

+0

Używanie Where() zamiast Find() było tym, co musiałem zrobić. Jednak twój pierwszy przykład musi używać expression.Compile() zamiast samego wyrażenia. Dzięki. –

+0

Zaktualizowano. Zaniedbałem fakt, że Where takes a Func . – tvanfosson

22

Kolejne opcje, które nie zostały wymienione:

Func<T, bool> func = expression.Compile(); 
Predicate<T> predicate = new Predicate<T>(func); 

To generuje taką samą IL jako

Func<T, bool> func = expression.Compile(); 
Predicate<T> predicate = func.Invoke; 
+4

dlaczego to ma tylko 12 głosów? jesteście niewdzięcznymi chłopami! To on, Jon Skeet. Posłuchaj jego słów !!!! – jokab

Powiązane problemy