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?










share|improve this question









New contributor




Razor Revenant is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • That doesn't compile. The var bodyExpr has a trailing },
    – MickyD
    yesterday

















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?










share|improve this question









New contributor




Razor Revenant is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • That doesn't compile. The var bodyExpr has a trailing },
    – MickyD
    yesterday















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?










share|improve this question









New contributor




Razor Revenant is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











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






share|improve this question









New contributor




Razor Revenant is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Razor Revenant is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited yesterday





















New contributor




Razor Revenant is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked yesterday









Razor Revenant

214




214




New contributor




Razor Revenant is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Razor Revenant is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Razor Revenant is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • That doesn't compile. The var 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






That doesn't compile. The var bodyExpr has a trailing },
– MickyD
yesterday














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, not lambdaMember.Body) - passing in the arguments to use for the parameters

  • rewrite the inner lambda at runtime using ExpressionVisitor - swapping out instances of the x from the inner expression with whatever you wanted to use as the argument - presumably paramExpr


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);





share|improve this answer























  • 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











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});






Razor Revenant is a new contributor. Be nice, and check out our Code of Conduct.










 

draft saved


draft discarded


















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

























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, not lambdaMember.Body) - passing in the arguments to use for the parameters

  • rewrite the inner lambda at runtime using ExpressionVisitor - swapping out instances of the x from the inner expression with whatever you wanted to use as the argument - presumably paramExpr


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);





share|improve this answer























  • 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















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, not lambdaMember.Body) - passing in the arguments to use for the parameters

  • rewrite the inner lambda at runtime using ExpressionVisitor - swapping out instances of the x from the inner expression with whatever you wanted to use as the argument - presumably paramExpr


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);





share|improve this answer























  • 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













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, not lambdaMember.Body) - passing in the arguments to use for the parameters

  • rewrite the inner lambda at runtime using ExpressionVisitor - swapping out instances of the x from the inner expression with whatever you wanted to use as the argument - presumably paramExpr


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);





share|improve this answer














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, not lambdaMember.Body) - passing in the arguments to use for the parameters

  • rewrite the inner lambda at runtime using ExpressionVisitor - swapping out instances of the x from the inner expression with whatever you wanted to use as the argument - presumably paramExpr


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);






share|improve this answer














share|improve this answer



share|improve this answer








edited yesterday

























answered yesterday









Marc Gravell

769k19021152528




769k19021152528












  • 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


















  • 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
















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










Razor Revenant is a new contributor. Be nice, and check out our Code of Conduct.










 

draft saved


draft discarded


















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.















 


draft saved


draft discarded














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





















































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







Popular posts from this blog

Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

A Topological Invariant for $pi_3(U(n))$