Expression tree expression, variables end as constants

So, I am working on a project where I need to parse an expression tree. I got most of the work, but I got a problem.

I looked at other questions in StackOverflow on expression trees, but cannot find the answer to my question, so here it goes.

My problem is the difference (or lack) between constants and variables. Let me start with an example:

user => user.Email == email

This is clearly not a constant, but a variable, but ultimately this is a ConstantExpression expression somewhere in the expression tree. If you look at the expression itself, it looks a little strange:

Expression = {value(stORM.Web.Security.User+<>c__DisplayClassa)}

If you take another example:

task => task.Status != TaskStatus.Done && t.Status != TaskStatus.Failed

Here I am using ENUM (TaskStatus).

, , , , ConstantExpression , . , , , , .

EDIT: , , . :

user = db.Search < > (u = > u.Email == email);

. , , , .

:

IList < a > tasks = db.Search(t = > t.Status!= TaskStatus.Done & t.Status!= TaskStatus.Failed);

, Done Failed. . , , . - , SQL , Done Failed.

+3
4

, . .

, , . "". , .

        int a =2;
        Expression<Func<int, int>> h = x=> x+ a;
        Expression<Func<int, int>> j = x => x +2;
        a = 1;

a , . node MemberAccess node, - .

:

((SimpleBinaryExpression)(h.Body)).Right
{value(WindowsFormsApplication6.Form1+<>c__DisplayClass0).a}
    CanReduce: false
    DebugView: ".Constant<WindowsFormsApplication6.Form1+<>c__DisplayClass0>(WindowsFormsApplication6.Form1+<>c__DisplayClass0).a"
    Expression: {value(WindowsFormsApplication6.Form1+<>c__DisplayClass0)}
    Member: {Int32 a}
    NodeType: MemberAccess
    Type: {Name = "Int32" FullName = "System.Int32"}

:

((MemberExpression)((SimpleBinaryExpression)(h.Body)).Right).Expression
{value(WindowsFormsApplication6.Form1+<>c__DisplayClass0)}
    CanReduce: false
    DebugView: ".Constant<WindowsFormsApplication6.Form1+<>c__DisplayClass0>(WindowsFormsApplication6.Form1+<>c__DisplayClass0)"
    NodeType: Constant
    Type: {Name = "<>c__DisplayClass0" FullName = "WindowsFormsApplication6.Form1+<>c__DisplayClass0"}
    Value: {WindowsFormsApplication6.Form1.}
        }
    }

2 :

((SimpleBinaryExpression)(j.Body)).Right
{2}
    CanReduce: false
    DebugView: "2"
    NodeType: Constant
    Type: {Name = "Int32" FullName = "System.Int32"}
    Value: 2

, . , node - , node.


-

,

user => user.Email == email

, , .

,

Expression<Func<User, string, bool>> (user, email) => user.Email == email

, . , , .

- , consts consts.

t => t.Status != TaskStatus.Done && t.Status != TaskStatus.Failed

: :

, , , , - - .

, - . , , - cloture, .

public static class Parameter
{
    public static T Input<T>(string name)
    {
        return default(T);
    }  
}

:

Expression<Func<User, bool>> exp = x => x.Email == Parameter.Input<String>("email");

- Parameter, ( ) .

+3

, .

.

+2

( email) ConstantExpression, , MemberExpression a FieldInfo "" - :

private class CaptureClass {
    public string email;
}
...
var obj = new CaptureClass();
obj.email = "foo@bar.com";

obj - .

: MemberExpression () ConstantExpression, , , . CompilerGeneratedAttribute ...

A literal constant will usually be simple ConstantExpression; in fact, it would be difficult to think of a scenario in which you use a constant member, unless you can something like:

() => "abc".Length

but here .Lengthis a property (not a field), and the string probably doesn't [CompilerGenerated].

+2
source

Just check the type of constant expression. Any constant expression of a constant has a primitive type.

0
source

Source: https://habr.com/ru/post/1785131/


All Articles