Convert Predicate<T> to Expression<Func<T, bool>>
Asked Answered
P

3

7

Is possible to convert a Predicate<T> to Expression<Func<T, bool>> in some way?

I would like to use the next IQueryable function using the filters of the my ICollectionView:

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

Thanks

Protege answered 21/3, 2012 at 10:1 Comment(4)
Difficult to do in a reasonable way(i.e. not by just wrapping it). That would involve decompiling IL to an expression.Credential
No. Predicate<T> is a compiled delegate. You could do such a thing, but with a Expression<Predicate<T>>.Cleocleobulus
@MarcCanalsGiraut: It seems like a bad idea... Why would you want to do this? Can't you change any of the existing code to avoid the problem in the first place?Fluorite
Don't forget to mark your favorite answer ;-)Agora
A
5

In theory it is possible to convert a delegate 'back' to an expression, because you can request the emitted IL of a delegate, which gives you the information you need to transform it back.

However, it's for a reason that neither LINQ to SQL and Entity Framework do this. It is complex, fragile, and performance intensive to do so.

So the short answer is, you can't transform it to an expression.

Agora answered 21/3, 2012 at 10:29 Comment(0)
P
6

Something like this?

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

You can probably make an extension Where method for your ICollectionView which takes a predicate, converts it to an Expression like this, and then call the Where method provided by Linq.

public static IQueryable<T> Where(this IQueryable<T> source, Predicate<T> predicate)
{
    return source.Where(x => predicate(x));
}
Protestantism answered 21/3, 2012 at 10:9 Comment(6)
-1: This wouldn't work in every case where the expression is not executed but analyzed like in LINQ to SQL, LINQ to EF, LINQ to NHibernate etc...Larrylars
Yes, I am aware. However, the asker mentioned that he needs it for his implementation of ICollectionView, which is used in WPF for GUI rendering, as seen here at the 'Remarks' section.Protestantism
It's the other way around :-) He wants to use the filters created for his ICollectionView in a Where clause.Larrylars
Just out of curiosity, what happens when you do new Func<string, bool>(predicate)? Is it converted to the Func so it can be analyzed, or does it get called and give the same result as explicitly calling the predicate?Protestantism
I don't know what happens when you do this, but it doesn't help you, because a Func<string, bool> isn't an Expression<Func<string, bool>> and can't be converted to one.Larrylars
I thought the Func was analysed when the Expression is called, but now I see I perceived it wrong. The Func is just there to strong type the Expression, but not actually perform the analysis on. Thank you for your explanation.Protestantism
A
5

In theory it is possible to convert a delegate 'back' to an expression, because you can request the emitted IL of a delegate, which gives you the information you need to transform it back.

However, it's for a reason that neither LINQ to SQL and Entity Framework do this. It is complex, fragile, and performance intensive to do so.

So the short answer is, you can't transform it to an expression.

Agora answered 21/3, 2012 at 10:29 Comment(0)
L
1
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 });
        }
    }
}
Lichter answered 11/7, 2014 at 16:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.