如何将Expression<Func<T, bool>>转换为Predicate<T>?

59

我有一个接受 Expression<Func<T, bool>> 参数的方法。我想将它作为 List.Find() 方法中的谓词,但似乎无法将其转换为 List 可以接受的 Predicate。你知道如何简单地实现此转换吗?

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);
}

更新

结合tvanfosson和280Z28的答案,我现在正在使用以下内容:

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

    return list.Where(expression.Compile()).ToList();
}
3个回答

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

编辑:根据评论,我们有更好的答案来回答第二行:

Predicate<T> pred = func.Invoke;

是的,func.Invoke 看起来更好。 - Lance Fisher

36

还有一个未被提及的选项:

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

这将生成与以下代码相同的IL:

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

8
为什么只有12个投票?你们这些不知感恩的农民!这是Jon Skeet。听从他的话吧!!! - jokab

28

我看不出需要这种方法,只需使用 Where()。

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

甚至更好的是,将表达式定义为内联lambda函数。

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

使用Where()而不是Find()是我需要做的。然而,你的第一个例子需要使用expression.Compile()而不仅仅是expression。谢谢。 - Lance Fisher
已更新。我忽略了 Where 方法需要一个 Func<T,bool> 参数的事实。 - tvanfosson
实际上,您可以使用 var sublist = list.Where(expression); - Prokurors

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接