Click here to Skip to main content
13,139,132 members (69,567 online)
Rate this:
Please Sign up or sign in to vote.
See more:
Say we have the following :
        private static string Query<T>(Expression<Func<T, bool>> pr)
            return pr.ToString();
int ii = 1000;
string str = Query((SalesInvoiceRow r) => r.Serial > ii && r.CustomerName.Contains( "23"));

When you run the above we get:
r => ((r.Serial > value(testing.program+<>c__DisplayClass0).ii) AndAlso r.CustomerName.Contains("23"))

How can we get the value of ii instead of the ugly statement like below?
r => ((r.Serial > 1000) AndAlso r.CustomerName.Contains("23"))
Posted 1-Feb-12 4:50am
Mehdi Gholam343.6K
Rate this: bad
Please Sign up or sign in to vote.

Solution 2

Hello Mehdi,

This is some experimental code to tweak with the ExpressionVisitor:

static void Main(string[] args)
    int a = 5;
    int b = 100;
    Expression<Func<int, bool>> expr = v => v > (a + b);
    WalkVisitor w = new WalkVisitor();
public class WalkVisitor : ExpressionVisitor
    protected override Expression VisitMember(MemberExpression node)
        var e = base.VisitMember(node);
        var c = node.Expression as ConstantExpression;
        if (c != null)
            Type t = c.Value.GetType();
            var x = t.InvokeMember(node.Member.Name, BindingFlags.GetField,
                                   null, c.Value, null);
            Console.WriteLine("{0} = {1}", node.ToString(), x);
        return e;

The output is:

value(ExprVisitor.Program+<>c__DisplayClass0).a = 5
value(ExprVisitor.Program+<>c__DisplayClass0).b = 100

You might need to implement a print visitor around this snippet...


Mehdi Gholam 1-Feb-12 14:34pm
Nice! but ExpressionVistor is a pain to wrap your head around I have seen this but it's a ton of code [for those who don't know me - I hate tonnes of code :) ]

5'ed anyway
Andreas Gieriet 1-Feb-12 14:55pm
Hello Mehdi,

Thanks for your 5!

So, we "suffer" the same ;-) "Less is often more!"

But I must admit: I like visitors for syntax traversing. Once you have the basic building blocks (traversing visitor, print visitor), additions and variations are usually tidy.

What is currently missing is the print visitor for the Expression syntax tree. Maybe I write an article about it if there is no such thing deeply buried somewhere of the web...

As for the troubles above: I suspect that the Value type of the ConstantExpression is wrong, at least for these lambda classes (DisplayClass...). I initially tried the VisitConstant() method, but there is no way to access the constant member of the class. Useless. So I had do analyze the call stack in the debugger and saw that the callee of the VisitConstant() was VisitMember().


Rate this: bad
Please Sign up or sign in to vote.

Solution 1

You should be able to compile the expression and then ToString it.


I just realized you want ii. I am totally confused now. Aren't you setting ii to 1000? Why do you now want the value?
Maybe you meant you want the query resolved. Well you should do what I posted then, Compile :)
Pete O'Hanlon 1-Feb-12 12:14pm
This was the problem I had. I couldn't quite see what he was after. Mehdi's a smart guy so I reckon it's something really esoteric.
Mehdi Gholam 1-Feb-12 14:30pm
Sorry Compile().ToString() gives : System.Func`2[testing.program+SalesInvoiceRow,System.Boolean]

What I am after is : ((r.Serial > 1000) AndAlso r.CustomerName.Contains("23")) where the ii is replaced with it's value not the ref to the variable.
Collin Jasnoch 1-Feb-12 14:49pm
OK I think I am starting to see what you are trying to do now. Never mind about the compile as it will execute it (I think we needed one more set of () though).
Yoru wording through me off. It sounded like you did not want the "Ugly statement bellow"... So I thought you were trying to execute the expression.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy |
Web03 | 2.8.170915.1 | Last Updated 1 Feb 2012
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100