【问题标题】:Convert Predicate<T> to Expression<Func<T, bool>>将 Predicate<T> 转换为 Expression<Func<T, bool>>
【发布时间】:2012-04-05 19:59:40
【问题描述】:

是否可以通过某种方式转换Predicate&lt;T&gt; to Expression&lt;Func&lt;T, bool&gt;&gt;

我想通过我的 ICollectionView 的过滤器使用下一个 IQueryable 函数:

public static System.Linq.IQueryable<TSource> Where<TSource>(this System.Linq.IQueryable<TSource> source, System.Linq.Expressions.Expression<System.Func<TSource, bool>> predicate)

谢谢

【问题讨论】:

  • 很难以合理的方式进行(即不只是包装它)。这将涉及将 IL 反编译为表达式。
  • 没有。 Predicate 是一个编译的委托。你可以做这样的事情,但使用 Expression>.
  • @MarcCanalsGiraut:这似乎是个坏主意……你为什么要这样做?你不能改变任何现有的代码来避免这个问题吗?
  • 别忘了标记你最喜欢的答案 ;-)

标签: c# expression iqueryable predicate icollectionview


【解决方案1】:

这样的?

Predicate<string> predicate = input => input.Length > 0;
Expression<Func<string, bool>> expression = (input) => predicate(input);

您可以为您的 ICollectionView 创建一个扩展 Where 方法,该方法接受一个谓词,将其转换为这样的表达式,然后调用 Linq 提供的 Where 方法。

public static IQueryable<T> Where(this IQueryable<T> source, Predicate<T> predicate)
{
    return source.Where(x => predicate(x));
}

【讨论】:

  • -1:这不适用于表达式未执行但分析的所有情况,如 LINQ to SQL、LINQ to EF、LINQ to NHibernate 等...
  • 是的,我知道。但是,提问者提到他需要它来实现 ICollectionView,它在 WPF 中用于 GUI 渲染,如“备注”部分中的 here 所示。
  • 正好相反 :-) 他想在Where 子句中使用为他的ICollectionView 创建的过滤器。
  • 我不知道当你这样做时会发生什么,但这对你没有帮助,因为 Func&lt;string, bool&gt; 不是 Expression&lt;Func&lt;string, bool&gt;&gt; 并且不能转换为一个。
  • 我以为在调用 Expression 时对 Func 进行了分析,但现在我发现我认为它是错误的。 Func 只是用来强类型表达式,但实际上并不执行分析。谢谢你的解释。
【解决方案2】:

理论上,可以将委托“返回”转换为表达式,因为您可以请求发出的委托 IL,这为您提供了将其转换回所需的信息。

但是,LINQ to SQL 和实体框架都没有这样做是有原因的。这样做是复杂、脆弱和性能密集型的。

所以简短的回答是,您不能将其转换为表达式。

【讨论】:

    【解决方案3】:
    namespace ConsoleApplication1
    {
        static class Extensions
        {
            public static Expression<Func<T, bool>> ToExpression<T>(this Predicate<T> p)
            {
                ParameterExpression p0 = Expression.Parameter(typeof(T));
                return Expression.Lambda<Func<T, bool>>(Expression.Call(p.Method, p0), 
                      new ParameterExpression[] { p0 });
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-18
      • 1970-01-01
      相关资源
      最近更新 更多