0

I'd like to be able to parse a Predicate and see the properties that have been set and the values to which they've been set. Is this possible?

For example, given a predicate of Person, I'd like to be able to see the expressions provided, as in:

Id > 5

or

Name = "Will"

etc.

I've been toying with different things, but I don't think I'm on the right path and I can't find an example. I did find this: Convert Predicate<T> to Expression<Func<T, bool>> but the responders seemed to strongly discourage this approach. Anyone have any thoughts on this?

For the record, I'm trying to convert the predicate to an inline SQL WHERE clause.

internal class Parser
{
    private IEnumerable<Person> people;
    public Parser(params Person[] people)
    {
        this.people = new List<Person>(people);
    }

    public IEnumerable<Person> Parse(Predicate<Person> predicate)
    {
        //IFormatter formatter = new BinaryFormatter();
        //IFormatterConverter converter = new FormatterConverter();
        //SerializationInfo info = new(typeof(Person), converter);
        //StreamingContext streamingContext = new StreamingContext();
        //predicate.GetObjectData(info, streamingContext);

        var invocationList = predicate.GetInvocationList();

        return Enumerable.Empty<Person>();
    }
}
Vic F
  • 1,143
  • 1
  • 11
  • 26
  • 1
    By the way, your actual question is "is it possible to parse a delegate" since a `Predicate` is declared as `public delegate bool Predicate(T obj);` – ProgrammingLlama Nov 25 '21 at 00:18
  • 1
    @Llama Thanks. I updated the title. – Vic F Nov 25 '21 at 00:19
  • I think your biggest issue is what a lambda expression becomes when your code gets compiled. See [here](https://sharplab.io/#v2:CYLg1APgAgTAjAWAFBQAwAIpwCwG5nJQDMmM6AwugN7Lp2YlTboCyAFAJTW328AqAUwDOAFzYAbdAF4AfOnEA6cgHsArgDsR6OQFYO+JLwC+POqYaZmg0WwAKAJwHAAlgGMAhiIEAeADLPRbwBlEXtndQBzGTkAB0cXDy8OcxpDehMkIyA==) - `l => l.Count > 5` has become a method: `internal bool b__0_0(List l)` – ProgrammingLlama Nov 25 '21 at 00:25
  • Yeah, that's not encouraging, is it? I have another solution to this problem (a custom class in place of the delegate), but I was hopeful that it might be possible to parse the predicate and extract out the elements being queried. – Vic F Nov 25 '21 at 00:33
  • 2
    You can't parse a delegate, but you can parse an expression, that's what tools like Entity Framework and LINQ 2 SQL do. The Expression class let's you look inside. You can declare and initialize an Expression and then go to town. There is (or was, haven't looked in a while) a 12 or 13 part blog series on how to create a LINQ provider. I looked at it a long time ago and it was daunting – Flydog57 Nov 25 '21 at 00:54
  • @Flydog57 Assuming I'm going to pursue this idea, are you suggesting that I try to convert the delegate to an expression or pass an expression into the method? – Vic F Nov 25 '21 at 00:58
  • @Vic You would need to pass an expression to the method. The code you found for converting a predicate to an expression simply makes a call to the delegate method, so it wouldn't help you. Accepting an `Expression>` actually produces an expression tree when compiled: [example](https://sharplab.io/#v2:CYLg1APgAgTAjAWAFBQAwAIpwHQBkCWAdgI7YCiAHgA4BOApgM4P4D2hDA3MmpnACxck3AMyYY6AMLoA3snTzMoqH3QBZABQBKGXIV6AKowAu6gDboAvAD50p7BJYBXQkfQ2ArJsF6Avrvn+ipgqhgwmlLSMzGwAPAAK9MD4AMYAhkZ0MQRhMQDKRjREAOZWpeiRSWkZmoGySL7IPkA=) – ProgrammingLlama Nov 25 '21 at 01:10
  • 3
    Instead of something like `Func pred = num => num%2==0;` you want to create an `Expression>` you may find _Predicate Builder_ (and related tools and source) useful – Flydog57 Nov 25 '21 at 01:19

0 Answers0