Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C#
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 5:50am
Mehdi Gholam250.3K
Rate this: bad
good
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();
    w.Visit(expr);
}
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...
 
Cheers
 
Andi
  Permalink  
Comments
Mehdi Gholam at 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 at 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().
 
Cheers
 
Andi
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

You should be able to compile the expression and then ToString it.
 
pr.Compile().ToString();
 
[Edit]
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 Smile | :)
  Permalink  
v3
Comments
Pete O'Hanlon at 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 at 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 at 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
0 OriginalGriff 605
1 Maciej Los 319
2 BillWoodruff 184
3 Richard MacCutchan 180
4 Suraj Sahoo | Coding Passion 180
0 OriginalGriff 8,654
1 Sergey Alexandrovich Kryukov 7,407
2 DamithSL 5,639
3 Maciej Los 5,229
4 Manas Bhardwaj 4,986


Advertise | Privacy | Mobile
Web01 | 2.8.1411023.1 | Last Updated 1 Feb 2012
Copyright © CodeProject, 1999-2014
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