Getting run-time value of a ParameterExpression in a expression tree - c#

I am missing the obvious: How do I access the value of a parameter inside a lambda expression expression tree?
Scenario: For a delegate x I dynamically create a lambda expression with an expression tree body which has the same signature as the delegate x. Inside the lamdba's body, I do some validation, checking, logging stuff (this is just testing code, not production), and then I invoke the original delegate x with the original parameters. If the delegate has a return value, this gets returned as well.
That works quite well (including passing the parameters to the original delegate).
But I am hitting a brick wall if I want to access the original parameter values passed to the delegate/lambda.
pseudo code:
var del = new Func<string, int>(_=> {return 42;});
var paramDefs = Array.ConvertAll<ParameterInfo, ParameterExpression>(del.Method.GetParameters(), _ => { return Expression.Parameter(_.ParameterType, _.Name); });
var variableTest = Expression.Variable(typeof(string), "str");
var expression = Expression.Block(
new [] { variableTest },
// this line assigns the actual run time value (which is what I need) of the parameter to the variable - but I cannot hardcode the index.
//Expression.Assign(variableTest, paramDefs[0])
// this line would assigns the ParameterExpression object (causing a run-time exception since the type of the variable is string) ... I need the _value_ of the first (or nth) parameter.
Expression.Assign(variableTest, Expression.ArrayIndex(Expression.Constant(paramDefs), Expression.Constant(0)))
);
var lamdba = Expression.Lambda(del.GetType(), expression, "foo", paramDefs);
var del2 = lamdba.Compile() as Func<string, int>;
del2("this is a test");

Looks like you confused the expression trees compiler too much (well, I was confused by this code too). I can see what you tried to do: you got an element from an array, then you decided to loop over the array. But you couldn't do array[ParameterExpression], so you used ArrayIndex. But...
But ArrayIndex in fact doesn't return "string". It returns MethodCallExpression. So, in this "Assign" expression you actually have ParameterExpression and MethodCallExpression. The ET compiler is smart enough to compile these expressions and try to assign results. But the result of your MethodCallExpression is ParameterExpression. When you had paramDefs[0], you had ParameterExpression right away and compiler could handle that. But compiling nested expressions is harder and it is totally unclear whether you really want to compile this nested expression or not.
What you can do is to compile and invoke the MethodCallExpression yourself, so you will have ParameterExpression in the Assign expression (as you had before).
It may look like this:
// Replace Assign in your Block expression.
Expression.Assign(variableTest, Expression.Lambda<Func<ParameterExpression>>(Expression.ArrayIndex(Expression.Constant(paramDefs), Expression.Constant(0))).Compile()()),
But it might be very heavy in terms of performance (plus the code is ugly). So, I'd stick with your idea of pulling the loop out of the expression tree.

Related

Build expression dynamically to call Expression.GreaterThan()

I'm trying to choose the method in Expression dynamically at runtime. For example, I want achieve something similar to what I'm trying below:
ConstantExpression one = Expression.Constant(1);
ConstantExpression two = Expression.Constant(2);
// Here the 'GreaterThan' is the method name received at runtime:
var method = typeof(Expression).GetMethods().Single(mi => mi.Name == "GreaterThan" && mi.GetParameters().Length == 2);
var expr = Expression.Call(method, one, two);
At the last line, I get the error:
System.ArgumentException: 'Expression of type 'System.Int32' cannot be used for parameter of type 'System.Linq.Expressions.Expression' of method 'System.Linq.Expressions.BinaryExpression GreaterThan(System.Linq.Expressions.Expression, System.Linq.Expressions.Expression)''
What I want to do is to build the lambda function by choosing methods in Expression dynamically at run time. Here, the method name will refer to some method that compares to numbers (or strings) depending on the expression method.
What exactly is dynamic? The operation values (i.e. the type of "one" and "two")? Or the type of the operation ("GreaterThan", "LessThen")?
If it's the former, you don't need to do anything as the expression builder will take care of it.
In
Expression.GreaterThan(Expression.Constant(1), Expression.Constant(2));
and
Expression.GreaterThan(Expression.Constant("Some"), Expression.Constant("text"));
the proper greater than operators for ints and strings will be automatically chosen.
If it's the latter you want, i.e. dynamically choosing the operation, you need to write
var expr = method.Invoke(null, new object[] { one, two });
Which means you need to invoke the expression method to get the GreaterThan expression thus yielding the same result as if you had written Expression.GreaterThan(one, two).
Calling Expression.Call on an expression method is akin to creating an expression to create expressions.
I think you should avoid using reflection here and use switch instead to build it. Using this approach allow to get all the benefits of strong typing. See https://www.codeproject.com/Articles/1079028/Build-Lambda-Expressions-Dynamically as an example.

What's the purpose of the Expression class?

I'm wondering what exactly is the difference between wrapping a delegate inside Expression<> and not ?
I'm seeing Expression<Foo> being used a lot with LinQ, but so far I've not found any article that explains the difference between this, and just using a delegate.
E.g.
Func<int, bool> Is42 = (value) => value == 42;
vs.
Expression<Func<int, bool>> Is42 = (value) => value == 42;
tl;dr, To have an expression is like having the source code of an application, and a delegate is an executable to run the application. An expression can be thought of as the "source" (i.e., syntax tree) of the code that would run. A delegate is a specific compilation that you would run and does the thing.
By storing a lambda as a delegate, you are storing a specific instance of a delegate that does some action. It can't be modified, you just call it. Once you have your delegate, you have limited options in inspecting what it does and whatnot.
By storing a lambda as an expression, you are storing an expression tree that represents the delegate. It can be manipulated to do other things like changing its parameters, changing the body and make it do something radically different. It could even be compiled back to a delegate so you may call it if you wish. You can easily inspect the expression to see what its parameters are, what it does and how it does it. This is something that a query provider can use to understand and translate an expression to another language (such as write an SQL query for a corresponding expression tree).
It is also a whole lot easier to create a delegate dynamically using expressions than it is emitting the code. You can think of your code at a higher level as expressions that is very similar to how a compiler views code instead of going low-level and view your code as IL instructions.
So with an expression, you are capable to do much more than a simple anonymous delegate. Though it's not really free, performance will take a hit if you run compiled expressions compared to a regular method or an anonymous delegate. But that might not be an issue as the other benefits to using expressions may be important to you.
Func<> is just a delegate type. An Expression is a runtime representation of the complete tree of operations which, optionally, may be compiled at runtime into a delegate. It's this tree that is parsed by Expression parsers like Linq-to-SQL to generate SQL statements or do other clever things. When you assign a lambda to an Expression type, the compiler generates this expression tree as well as the usual IL code. More on expression trees.
To illustrate other answers, if you compile those 2 expressions and have look at the compiler generated code, this i what you will see:
Func<int, bool> Is42 = (value) => value == 42;
Func<int, bool> Is42 = new Func<int, bool>((#value) => value == 42);
Expression<Func<int, bool>> Is42 = (value) => value == 42;
ParameterExpression[] parameterExpressionArray;
ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "value");
Expression<Func<int, bool>> Is42 = Expression.Lambda<Func<int, bool>>(Expression.Equal(parameterExpression, Expression.Constant(42, typeof(int))), new ParameterExpression[] { parameterExpression });
Expression Trees allow you to inspect the code inside the expression, in your code.
For example, if you passed this expression: o => o.Name, your code could find out that the Name property was being accessed inside the expression.
Provides the base class from which the classes that represent
expression tree nodes are derived.
System.Linq.Expressions.BinaryExpression
System.Linq.Expressions.BlockExpression
System.Linq.Expressions.ConditionalExpression
System.Linq.Expressions.ConstantExpression
System.Linq.Expressions.DebugInfoExpression
System.Linq.Expressions.DefaultExpression
System.Linq.Expressions.DynamicExpression
System.Linq.Expressions.GotoExpression
System.Linq.Expressions.IndexExpression
System.Linq.Expressions.InvocationExpression
System.Linq.Expressions.LabelExpression
System.Linq.Expressions.LambdaExpression
System.Linq.Expressions.ListInitExpression
System.Linq.Expressions.LoopExpression
System.Linq.Expressions.MemberExpression
System.Linq.Expressions.MemberInitExpression
System.Linq.Expressions.MethodCallExpression
System.Linq.Expressions.NewArrayExpression
System.Linq.Expressions.NewExpression
System.Linq.Expressions.ParameterExpression
System.Linq.Expressions.RuntimeVariablesExpression
System.Linq.Expressions.SwitchExpression
System.Linq.Expressions.TryExpression
System.Linq.Expressions.TypeBinaryExpression
System.Linq.Expressions.UnaryExpression
http://msdn.microsoft.com/en-us/library/system.linq.expressions.expression.aspx
Expression tree represents linq expression that can be analyzed and for example turned into SQL query.
To whatever the other wrote (that is completely correct) I'll add that through the Expression class you can create new methods at runtime. There are some limits. Not all the things you can do in C# can be done in an Expression tree (at least in .NET 3.5 . With .NET 4.0 they have added a great number of possible Expression "types"). The use of this could be (for example) to create a dynamic query and pass it to LINQ-to-SQL or do some filtering based on the input of the user... (you could always do this with CodeDom if all you wanted was a dynamic method incompatible with LINQ-to-SQL, but emitting directly IL code is quite difficult :-) )

Trying to understand what an expression tree is

Both snippets below product the same output.
I understand how Func encapsulates a method with a single parameter, and returns a bool value. And you can either assign it a
method, anonymous method or a lambda expression.
Func<int, bool> deleg = i => i < 5;
Console.WriteLine("deleg(4) = {0}", deleg(4));
Below is using expression trees which I don't fully understand yet. Why would I want to do it this way? Is it more flexible, what advantage does it give me?
System.Linq.Expressions.Expression<Func<int, bool>> expr = i => i < 5;
Func<int, bool> deleg2 = expr.Compile();
Console.WriteLine("deleg2(4) = {0}", deleg2(4));
Basically, the Expression tree is the body of a lambda expression, that allows you to
introspect the expression (see what's in it so to say)
manipulate the expression (simplify, extend (e.g. add new functionality or modify to work on different items).
Once you Compile() the expression, it is just another delegate, which you can only call, not inspect or modify.
Whenever you want to
create expressions dynamically (I mean: construct, not allocate)
operate on expressions dynamically
the Function<> types are not sufficient.
The point of expression trees is that you can do more with them than just compile them to a function. You can inspect them, modify them and compile them to something other than .net functions.
For example Linq2SQL compiles expression trees to SQL code. You couldn't do that with a plain .net function.
In your first example you just have "hardcoded" the body of the function and assigned it to a delegate.
In your second example the assignment constructs an expression-tree which is an object model reprensenting your code in a data structure in memory.
The advantage is that you can modify and inspect that datastructure.
LINQ2SQL for example uses that technique to translate your expressions to another language called SQL.
Expression trees are regular in-memory data structures that can be traversed programmatically and the result of such traversal can be something, like a query you'd like to send to the database. Read more on the ExpressionVisitor class to see how it is done.
On the other hand, the compiled function is nothing more than a sequence of CIL code. You still can inspect it programmatically but you are not inspecting the definition but rather - the compiler output of it.

difference between Expression and Func

What is the difference between Expression and Func? The same task can be attained by both. So what is the difference?
Expression trees are data representations of logic - which means they can be examined at execution time by things like LINQ providers. They can work out what the code means, and possibly convert it into another form, such as SQL.
The Func family of types, however, are just delegates. They end up as normal IL, which can be executed directly, but not (easily) examined. Note that you can compile expression trees (well, Expression<T> and LambdaExpression) into delegates and execute those within managed code as well, if you need to.
You can build up expression trees manually using the factory methods in the Expression class, but usually you just use the fact that C# can convert lambda expressions into both expression trees and normal delegates:
Expression<Func<int, int>> square = x => x * x;
Func<int, int> square = x => x * x;
Note that there are limitations on which lambda expressions can be converted into expression trees. Most importantly, only lambdas consisting of a single expression (rather than a statement body) can be converted:
// Compile-time error
Expression<Func<int, int>> square = x => { return x * x; };
// Works fine
Func<int, int> square = x => { return x * x; };
It is not true that "they do the same thing". Expression describes your intent in a way that can be interpreted at runtime - it is, if you like, the recipe. A function is an opaque delegate, that can't be inspected - it can be used as a black box. Compared to a recipe, it is some kind of auto-chef that doesn't let you see what it does: give it some bread and some chicken, close your eyes and it gives you a sandwich, but you never get to know how.
I discuss this more here: Explaining Expression, but having the recipe is key for LINQ, RPC, etc. And of course, if you have the recipe you can make your own chef, via Expression.Compile().
Expression can be built at runtime, function not (unless you use reflection emit). Once you build the expression tree you can compile it and turn it into a function pointer which can be invoked. Func is a pointer to some already existing function which can no longer be modified while Expression represents the code of some function that doesn't exist until you compile it.
You usually use expressions when you want to preserve the semantics of the code so that you can translate it. That is, expressions allow you to treat the code as data. If the code does not need to be treated as data (i.e. you're not planning on storing it or translating it) then using a Func is appropriate.

Is it possible to cast a delegate instance into a Lambda expression?

Here the context for my question:
A common technique is to declare the parameter of a method as a Lambda expression rather than a delegate. This is so that the method can examine the expression to do interesting things like find out the names of method calls in the body of the delegate instance.
Problem is that you lose some of the intelli-sense features of Resharper. If the parameter of the method was declared as a delegate, Resharper would help out when writing the call to this method, prompting you with the x => x syntax to supply as the argument value to this method.
So... back to my question I would like to do the follow:
MethodThatTakesDelegate(s => s.Length);
}
private void MethodThatTakesDelegate(Func<string, object> func)
{
//convert func into expression
//Expression<Func<string, object>> expr = "code I need to write"
MethodThatTakesExpression(expr);
}
private void MethodThatTakesExpression(Expression<Func<string, object>> expr)
{
//code here to determine the name of the property called against string (ie the Length)
}
Everywhere that you're using the term "lambda expression" you actually mean "expression tree".
A lambda expression is the bit in source code which is
parameters => code
e.g.
x => x * 2
Expression trees are instances of the System.Linq.Expressions.Expression class (or rather, one of the derived classes) which represent code as data.
Lambda expressions are converted by the compiler into either expression trees (or rather, code which generates an expression tree at execution time) or delegate instances.
You can compile an instance of LambdaExpression (which is one of the subclasses of Expression) into a delegate, but you can't go the other way round.
In theory it might be possible to write such a "decompiler" based on the IL returned by MethodBase.GetMethodBody in some situations, but currently there are various delegates which can't be represented by expression trees. An expression tree represents an expression rather than a statement or statement block - so there's no looping, branching (except conditionals), assignment etc. I believe this may change in .NET 4.0, though I wouldn't expect a decompilation step from Microsoft unless there's a really good reason for one.
I don't believe it's possible to achieve what you'd like here. From the comments in your code it looks like you are attempting to capture the name of the property which did the assignment in MethodThatTakesExpression. This requires an expression tree lambda expression which captures the contexnt of the property access.
At the point you pass a delegate into MethodThatTakesDelegate this context is lost. Delegates only store a method address not any context about the method information. Once this conversion is made it's not possible to get it back.
An example of why this is not possible is that there might not even be a named method backing a delegate. It's possible to use ReflectionEmit to generate a method which has no name whatsoever and only exists in memory. It is possible though to assign this out to a Func object.
No, it is not possible.

Categories

Resources