Complex Expression Tree with no changing context of param
up vote
3
down vote
favorite
i need to dinamically generate expression like this:
Expression<Func<MyClass, bool>> expr = x => (x.SomeField.CompareTo(someValue) <= 0);
trying to do it like this:
var paramExpr = Expression.Parameter(typeof(MyClass), "x");
Expression<Func<MyClass, FieldType>> pathToField = x => x.SomeField;
Expression path = pathToField;
if (!(path is LambdaExpression lambdaMember))
throw ...;
Expression valueExpr = Expression.Constant(someValue);
var bodyExpr = Expression.LessThanOrEqual(Expression.Call(lambdaMember.Body, "CompareTo", null, valueExpr ), Expression.Constant(0));
return Expression.Lambda<Func<MyClass, FieldType>>(bodyExpr, paramExpr);
but always getting error when trying to compile this:
variable 'x' of type 'MyClass' referenced from scope '', but it is not defined
how i could do this correctly?
c# reflection expression-trees
New contributor
add a comment |
up vote
3
down vote
favorite
i need to dinamically generate expression like this:
Expression<Func<MyClass, bool>> expr = x => (x.SomeField.CompareTo(someValue) <= 0);
trying to do it like this:
var paramExpr = Expression.Parameter(typeof(MyClass), "x");
Expression<Func<MyClass, FieldType>> pathToField = x => x.SomeField;
Expression path = pathToField;
if (!(path is LambdaExpression lambdaMember))
throw ...;
Expression valueExpr = Expression.Constant(someValue);
var bodyExpr = Expression.LessThanOrEqual(Expression.Call(lambdaMember.Body, "CompareTo", null, valueExpr ), Expression.Constant(0));
return Expression.Lambda<Func<MyClass, FieldType>>(bodyExpr, paramExpr);
but always getting error when trying to compile this:
variable 'x' of type 'MyClass' referenced from scope '', but it is not defined
how i could do this correctly?
c# reflection expression-trees
New contributor
That doesn't compile. Thevar bodyExpr
has a trailing},
– MickyD
yesterday
add a comment |
up vote
3
down vote
favorite
up vote
3
down vote
favorite
i need to dinamically generate expression like this:
Expression<Func<MyClass, bool>> expr = x => (x.SomeField.CompareTo(someValue) <= 0);
trying to do it like this:
var paramExpr = Expression.Parameter(typeof(MyClass), "x");
Expression<Func<MyClass, FieldType>> pathToField = x => x.SomeField;
Expression path = pathToField;
if (!(path is LambdaExpression lambdaMember))
throw ...;
Expression valueExpr = Expression.Constant(someValue);
var bodyExpr = Expression.LessThanOrEqual(Expression.Call(lambdaMember.Body, "CompareTo", null, valueExpr ), Expression.Constant(0));
return Expression.Lambda<Func<MyClass, FieldType>>(bodyExpr, paramExpr);
but always getting error when trying to compile this:
variable 'x' of type 'MyClass' referenced from scope '', but it is not defined
how i could do this correctly?
c# reflection expression-trees
New contributor
i need to dinamically generate expression like this:
Expression<Func<MyClass, bool>> expr = x => (x.SomeField.CompareTo(someValue) <= 0);
trying to do it like this:
var paramExpr = Expression.Parameter(typeof(MyClass), "x");
Expression<Func<MyClass, FieldType>> pathToField = x => x.SomeField;
Expression path = pathToField;
if (!(path is LambdaExpression lambdaMember))
throw ...;
Expression valueExpr = Expression.Constant(someValue);
var bodyExpr = Expression.LessThanOrEqual(Expression.Call(lambdaMember.Body, "CompareTo", null, valueExpr ), Expression.Constant(0));
return Expression.Lambda<Func<MyClass, FieldType>>(bodyExpr, paramExpr);
but always getting error when trying to compile this:
variable 'x' of type 'MyClass' referenced from scope '', but it is not defined
how i could do this correctly?
c# reflection expression-trees
c# reflection expression-trees
New contributor
New contributor
edited yesterday
New contributor
asked yesterday
Razor Revenant
214
214
New contributor
New contributor
That doesn't compile. Thevar bodyExpr
has a trailing},
– MickyD
yesterday
add a comment |
That doesn't compile. Thevar bodyExpr
has a trailing},
– MickyD
yesterday
That doesn't compile. The
var bodyExpr
has a trailing },
– MickyD
yesterday
That doesn't compile. The
var bodyExpr
has a trailing },
– MickyD
yesterday
add a comment |
1 Answer
1
active
oldest
votes
up vote
4
down vote
accepted
The problem here is that you're using lambdaMember.Body
, which references the x
from x => x.SomeField
- but because you only used the .Body
, that is undefined - and is unrelated to the x
from Expression.Parameter(typeof(MyClass), "x");
In the general case, there are 2 options here:
- invoke the entire lambda (i.e.
lambdaMember
, notlambdaMember.Body
) - passing in the arguments to use for the parameters - rewrite the inner lambda at runtime using
ExpressionVisitor
- swapping out instances of thex
from the inner expression with whatever you wanted to use as the argument - presumablyparamExpr
The first option is easier, and is just Expression.Invoke
:
var bodyExpr = Expression.LessThanOrEqual(
Expression.Call(Expression.Invoke(lambdaMember, paramExpr),
"CompareTo", null, valueExpr), Expression.Constant(0));
Note: there is a third option in this case, since it is a relatively simple example - you can just hijack the parameter from the inner expression and use it instead of declaring paramExpr
as a new parameter expression:
var paramExpr = lambdaMember.Parameters.Single();
Expression valueExpr = Expression.Constant(someValue);
var bodyExpr = Expression.LessThanOrEqual(
Expression.Call(lambdaMember.Body,
"CompareTo", null, valueExpr), Expression.Constant(0));
return Expression.Lambda<Func<MyClass, FieldType>>(bodyExpr, lambdaMember.Parameters);
Thank you, but in third option u just getx => x.Field.CompareTo(value)
, notx => x.Field.CompareTo(value) <= 0
– Razor Revenant
yesterday
@RazorRevenant no, you don't; I think you've made a transcription error from the example I gave
– Marc Gravell♦
yesterday
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
accepted
The problem here is that you're using lambdaMember.Body
, which references the x
from x => x.SomeField
- but because you only used the .Body
, that is undefined - and is unrelated to the x
from Expression.Parameter(typeof(MyClass), "x");
In the general case, there are 2 options here:
- invoke the entire lambda (i.e.
lambdaMember
, notlambdaMember.Body
) - passing in the arguments to use for the parameters - rewrite the inner lambda at runtime using
ExpressionVisitor
- swapping out instances of thex
from the inner expression with whatever you wanted to use as the argument - presumablyparamExpr
The first option is easier, and is just Expression.Invoke
:
var bodyExpr = Expression.LessThanOrEqual(
Expression.Call(Expression.Invoke(lambdaMember, paramExpr),
"CompareTo", null, valueExpr), Expression.Constant(0));
Note: there is a third option in this case, since it is a relatively simple example - you can just hijack the parameter from the inner expression and use it instead of declaring paramExpr
as a new parameter expression:
var paramExpr = lambdaMember.Parameters.Single();
Expression valueExpr = Expression.Constant(someValue);
var bodyExpr = Expression.LessThanOrEqual(
Expression.Call(lambdaMember.Body,
"CompareTo", null, valueExpr), Expression.Constant(0));
return Expression.Lambda<Func<MyClass, FieldType>>(bodyExpr, lambdaMember.Parameters);
Thank you, but in third option u just getx => x.Field.CompareTo(value)
, notx => x.Field.CompareTo(value) <= 0
– Razor Revenant
yesterday
@RazorRevenant no, you don't; I think you've made a transcription error from the example I gave
– Marc Gravell♦
yesterday
add a comment |
up vote
4
down vote
accepted
The problem here is that you're using lambdaMember.Body
, which references the x
from x => x.SomeField
- but because you only used the .Body
, that is undefined - and is unrelated to the x
from Expression.Parameter(typeof(MyClass), "x");
In the general case, there are 2 options here:
- invoke the entire lambda (i.e.
lambdaMember
, notlambdaMember.Body
) - passing in the arguments to use for the parameters - rewrite the inner lambda at runtime using
ExpressionVisitor
- swapping out instances of thex
from the inner expression with whatever you wanted to use as the argument - presumablyparamExpr
The first option is easier, and is just Expression.Invoke
:
var bodyExpr = Expression.LessThanOrEqual(
Expression.Call(Expression.Invoke(lambdaMember, paramExpr),
"CompareTo", null, valueExpr), Expression.Constant(0));
Note: there is a third option in this case, since it is a relatively simple example - you can just hijack the parameter from the inner expression and use it instead of declaring paramExpr
as a new parameter expression:
var paramExpr = lambdaMember.Parameters.Single();
Expression valueExpr = Expression.Constant(someValue);
var bodyExpr = Expression.LessThanOrEqual(
Expression.Call(lambdaMember.Body,
"CompareTo", null, valueExpr), Expression.Constant(0));
return Expression.Lambda<Func<MyClass, FieldType>>(bodyExpr, lambdaMember.Parameters);
Thank you, but in third option u just getx => x.Field.CompareTo(value)
, notx => x.Field.CompareTo(value) <= 0
– Razor Revenant
yesterday
@RazorRevenant no, you don't; I think you've made a transcription error from the example I gave
– Marc Gravell♦
yesterday
add a comment |
up vote
4
down vote
accepted
up vote
4
down vote
accepted
The problem here is that you're using lambdaMember.Body
, which references the x
from x => x.SomeField
- but because you only used the .Body
, that is undefined - and is unrelated to the x
from Expression.Parameter(typeof(MyClass), "x");
In the general case, there are 2 options here:
- invoke the entire lambda (i.e.
lambdaMember
, notlambdaMember.Body
) - passing in the arguments to use for the parameters - rewrite the inner lambda at runtime using
ExpressionVisitor
- swapping out instances of thex
from the inner expression with whatever you wanted to use as the argument - presumablyparamExpr
The first option is easier, and is just Expression.Invoke
:
var bodyExpr = Expression.LessThanOrEqual(
Expression.Call(Expression.Invoke(lambdaMember, paramExpr),
"CompareTo", null, valueExpr), Expression.Constant(0));
Note: there is a third option in this case, since it is a relatively simple example - you can just hijack the parameter from the inner expression and use it instead of declaring paramExpr
as a new parameter expression:
var paramExpr = lambdaMember.Parameters.Single();
Expression valueExpr = Expression.Constant(someValue);
var bodyExpr = Expression.LessThanOrEqual(
Expression.Call(lambdaMember.Body,
"CompareTo", null, valueExpr), Expression.Constant(0));
return Expression.Lambda<Func<MyClass, FieldType>>(bodyExpr, lambdaMember.Parameters);
The problem here is that you're using lambdaMember.Body
, which references the x
from x => x.SomeField
- but because you only used the .Body
, that is undefined - and is unrelated to the x
from Expression.Parameter(typeof(MyClass), "x");
In the general case, there are 2 options here:
- invoke the entire lambda (i.e.
lambdaMember
, notlambdaMember.Body
) - passing in the arguments to use for the parameters - rewrite the inner lambda at runtime using
ExpressionVisitor
- swapping out instances of thex
from the inner expression with whatever you wanted to use as the argument - presumablyparamExpr
The first option is easier, and is just Expression.Invoke
:
var bodyExpr = Expression.LessThanOrEqual(
Expression.Call(Expression.Invoke(lambdaMember, paramExpr),
"CompareTo", null, valueExpr), Expression.Constant(0));
Note: there is a third option in this case, since it is a relatively simple example - you can just hijack the parameter from the inner expression and use it instead of declaring paramExpr
as a new parameter expression:
var paramExpr = lambdaMember.Parameters.Single();
Expression valueExpr = Expression.Constant(someValue);
var bodyExpr = Expression.LessThanOrEqual(
Expression.Call(lambdaMember.Body,
"CompareTo", null, valueExpr), Expression.Constant(0));
return Expression.Lambda<Func<MyClass, FieldType>>(bodyExpr, lambdaMember.Parameters);
edited yesterday
answered yesterday
Marc Gravell♦
769k19021152528
769k19021152528
Thank you, but in third option u just getx => x.Field.CompareTo(value)
, notx => x.Field.CompareTo(value) <= 0
– Razor Revenant
yesterday
@RazorRevenant no, you don't; I think you've made a transcription error from the example I gave
– Marc Gravell♦
yesterday
add a comment |
Thank you, but in third option u just getx => x.Field.CompareTo(value)
, notx => x.Field.CompareTo(value) <= 0
– Razor Revenant
yesterday
@RazorRevenant no, you don't; I think you've made a transcription error from the example I gave
– Marc Gravell♦
yesterday
Thank you, but in third option u just get
x => x.Field.CompareTo(value)
, not x => x.Field.CompareTo(value) <= 0
– Razor Revenant
yesterday
Thank you, but in third option u just get
x => x.Field.CompareTo(value)
, not x => x.Field.CompareTo(value) <= 0
– Razor Revenant
yesterday
@RazorRevenant no, you don't; I think you've made a transcription error from the example I gave
– Marc Gravell♦
yesterday
@RazorRevenant no, you don't; I think you've made a transcription error from the example I gave
– Marc Gravell♦
yesterday
add a comment |
Razor Revenant is a new contributor. Be nice, and check out our Code of Conduct.
Razor Revenant is a new contributor. Be nice, and check out our Code of Conduct.
Razor Revenant is a new contributor. Be nice, and check out our Code of Conduct.
Razor Revenant is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53372563%2fcomplex-expression-tree-with-no-changing-context-of-param%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
That doesn't compile. The
var bodyExpr
has a trailing},
– MickyD
yesterday