Getting the result from an Expression - c#

I've created a lambda expression at runtime, and want to evaluate it - how do I do that? I just want to run the expression by itself, not against any collection or other values.
At this stage, once it's created, I can see that it is of type Expression<Func<bool>>, with a value of {() => "MyValue".StartsWith("MyV")}.
I thought at that point I could just call var result = Expression.Invoke(expr, null); against it, and I'd have my boolean result. But that just returns an InvocationExpression, which in the debugger looks like {Invoke(() => "MyValue".StartsWith("MyV"))}.
I'm pretty sure I'm close, but can't figure out how to get my result!
Thanks.

Try compiling the expression with the Compile method then invoking the delegate that is returned:
using System;
using System.Linq.Expressions;
class Example
{
static void Main()
{
Expression<Func<Boolean>> expression
= () => "MyValue".StartsWith("MyV");
Func<Boolean> func = expression.Compile();
Boolean result = func();
}
}

As Andrew mentioned, you have to compile an Expression before you can execute it. The other option is to not use an Expression at all, which woul dlook like this:
Func<Boolean> MyLambda = () => "MyValue".StartsWith("MyV");
var Result = MyLambda();
In this example, the lambda expression is compiled when you build your project, instead of being transformed into an expression tree. If you are not dynamically manipulating expression trees or using a library that uses expression trees (Linq to Sql, Linq to Entities, etc), then it can make more sense to do it this way.

The way I would do it is lifted right from here: MSDN example
delegate int del(int i);
static void Main(string[] args)
{
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
}
Also if you want to use an Expression<TDelegate> type then this page: Expression(TDelegate) Class (System.Linq.Expression) has the following example:
// Lambda expression as executable code.
Func<int, bool> deleg = i => i < 5;
// Invoke the delegate and display the output.
Console.WriteLine("deleg(4) = {0}", deleg(4));
// Lambda expression as data in the form of an expression tree.
System.Linq.Expressions.Expression<Func<int, bool>> expr = i => i < 5;
// Compile the expression tree into executable code.
Func<int, bool> deleg2 = expr.Compile();
// Invoke the method and print the output.
Console.WriteLine("deleg2(4) = {0}", deleg2(4));
/* This code produces the following output:
deleg(4) = True
deleg2(4) = True
*/

Related

Use of Expression in LINQ query

I have an Expression which could be any value. For example it could be () => 5 + 5. How would I use that Expression to search a List<int> to return true if the value is found in the List<int>? What I'm trying to do is I'm given an Expression and I'm checking a list to see if the value of the Expression is in the list
private int FindRecord(System.Linq.Expressions.Expression expression)
{
// expression when stepping through in debug is {() => 5 + 5}
List<int> list = new List<int>();
list.Add(5);
list.Add(10);
return list.Any(expression); // syntax issue - cannot convert from Expression to Func<int,bool>
}
EDIT : I misunderstood the question so here is my new answer:
private bool FindRecord(System.Linq.Expressions.Expression<Func<int>> expression)
{
int valueToSearch = expression.Compile()();
List<int> list = new List<int>();
list.Add(5);
list.Add(10);
return list.Any(i => i == valueToSearch); // syntax issue - cannot convert from Expression to Func<int,bool>
}
The return type of you function should be a "bool" (Any return a bool, not an int).
Parameter type "Expression" is not accurate enough, you should say it's a expression of a function return an integer.
You need to compile this expression to be able to "run" it and to get the actual value.
Well, you can do it as follows without Compile() on the Expression parameter, but it's really not a good idea. You generally don't want to be passing Expression around in your code as it will fail at runtime instead of compile time. You should change your method to accept an Expression of the expected type instead, or make it generic.
private static bool FindRecord(Expression expression, IEnumerable<int> list)
{
ParameterExpression parameter = Expression.Parameter(typeof(int), "x");
Expression body = Expression.Equal(parameter, Expression.Invoke(expression));
Expression<Func<int, bool>> lambda = (Expression<Func<int, bool>>)Expression.Lambda(body, parameter);
Console.WriteLine(lambda);
return list.Any(lambda.Compile());
}

How does linq Expression<TDelegate> assignment work on a language syntax level

TLDR: How does this compile?
class A{};
Expression<Func<A, int>> e = x => 24; // I don't understant what makes this compile
// and what happens at this assignment
What is the minimum class E to be able to compile E e = x => 24;
Some investigation
class E {};
E e = x => 24;
Visual Studio error is "Cannot convert lambda expression to type 'E' because it is not a delegate type" which is confusing because as far as I know a delegate is declared like this:
int delegate MyHandle();
and I didn't find any way of making a class a delegate.
Furthermore I have looked at the metadata of Expression -> LambdaExpression -> Expression<TDelegate> and wasn't able to identify what syntax/declaration makes Expression<TDelegate> act like a delegate.
Even more I have tried to create my own class E to mimic Expression<TDelegate> and I wasn't even able to compile the class
// basically a copy-paste of the metadata of `Expression<TDelegate>`
public sealed class E<TDelegate> : LambdaExpression
{
public TDelegate Compile() => default(TDelegate);
public TDelegate Compile(DebugInfoGenerator debugInfoGenerator) => default(TDelegate);
public TDelegate Compile(bool preferInterpretation) => default(TDelegate);
public Expression Update(Expression body, IEnumerable<ParameterExpression> parameters)
=> default(Expression);
protected override Expression Accept(ExpressionVisitor visitor) => null;
}
getting the error "'LambdaExpression' does not contain a constructor that takes 0 arguments"
Context (can be skipped):
I am getting started with Moq and because I just cannot take things for granted I am trying to understand how it works / how it is implemented. So this the first part of a series of inquiries about that.
I am now specifically trying to understand
public class A
{
public virtual int Foo() => throw new NotImplementedException();
public virtual int Bar() => throw new NotImplementedException();
}
var a = new Mock<A>();
a.Setup(x => x.Foo()).Returns(24); // ??
Console.WriteLine(a.Object.Foo());
I am trying to understand how the information "the method Foo" is passed to a
by passing that lambda? As far as I know a lambda is just a callable object, but somehow magically a knows the actual body of the lambda, i.e. will throw if you pass x => 24 or x => x.Foo() + x.Bar() but will accept x => x.Foo()
And I see that Setup parameter is of type Expression<Func<A, int>> hence my current question.
The C# specification gives special treatment to System.Linq.Expressions.Expression<D>; you cannot get the same treatment for your own type.
Expression trees permit lambda expressions to be represented as data structures instead of executable code. Expression trees are values of expression tree types of the form System.Linq.Expressions.Expression<D>, where D is any delegate type.
Source: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/types#expression-tree-types
This is a Lambda expression:
x => 24
According to MSDN Lambda expressions a lambda expression can be used to create a delegate or an expression tree type.
A Func<T, int> is a delegate function that takes a T as input and returns an int as output. If you assign the lambda expression above to this Func, then the compiler assumes that the x in the lambda expression is the input of the Func, and the part after the => is the output of the Func:
Func<string, int> func = x => x.Length;
Here x is expected to be a string, the part after the => may use, but is not obliged to use, this x to produce the output which has to be an int.
Func<int, int> func = x => x = -x;
Here x is expected to be an int. The return of the function is -x which is also an int.
Expression is the base class of all kinds of expressions. Expressions represent an operation that return a value. The most basic expressions are constants, they represent just a constant value, like 24. Other expressions might be additions, which take as input two expressions and have one output value. Other expressions are multiplication, negation, etc, which return a "number", or boolean expressions like AND OR NOR etc which return a Boolean.
A special kind of expression (so a derived class) is a LambdaExpression. A LambdaExpression usually represents a function-like object: it has zero or more input parameters and one output parameter. You assign a value to a LambdaExpression using a lambda expression (note the space in lambda expression!):
Expression<Func<string, int>> myExpression = x => x.Length;
I wrote earlier what the lambda expression x => x.Length does. the statement above creates an object of type System.Linq.Expressions.Expression<TDelegate>, which is of type LambdaExpression, hence you can assign it to an Expression<Func<string, int>>.
Your question:
What is the minimum class E to be able to compile E e = x => 24?
Your class E will need a constructor (or assignment operator) that accepts a System.Linq.Expressions.Expression<Func<MyClass, int> as parameter. If you don't use the x from your lambda expression MyClass can be object
Of course it is also accepted if the constructor takes any of the base classes, like Expression. However, if you do so you won't be able to used any of the Expression<Func<MyClass, int> functionality.
About your Mock code
Apparently you have a class A with two functions Foo and Bar, and you want to instantiate a Mock object to mock the functionality of A.
var myAmock = new Mock<A>();
myAmock.Setup(x => x.Foo()).Returns(24);
This says, that myAmock is an object that should mock behaviour of class A. Whenever someone calls the Foo function it should return a value of 24.

Call Any inside Expression and pass the delegate

I have a scenario here where I need to hit a dynamic query using linq (with nhibernate). The final query should look like this:
long[] values = { ... };
var result = Queryable<Entity>.Where(x => x.Documents.Any(d => values.Contains(d.Id)))
.ToList();
The generic Entity and the property Documents can change and it will be defined by some user configurations. The type of collection Documents is ICollection<T> where T is Document type. I am trying to create an Expression tree to define these statements dynamically but I am getting some issues. Look the code and comments bellow of what I have tried.
I have create this function to return the delagate I want to use inside the Any method:
public static Func<T, bool> GetFunc<T>(long[] values)
where T : Entity
{
return x => values.Contains(x.Id);
}
And I am using the Expression class to make the expression like this (see code and comments):
// define my parameter of expression
var parameter = Expression.Parameter(typeof(T), "x");
// I get an array of IDs (long) as argument and transform it on an Expression
var valuesExpression = Expression.Constant(values);
// define the access to my collection property. propertyFilter is propertyinfo for the `Documents` of the sample above.
// I get an expression to represent: x.Documents
var collectionPropertyExpression = Expression.Property(parameter, propertyFilter);
// get the T generic type of the ICollection<T> from propertyFilter. I get the `Documents` of sample above.
var entityFilterType = propertyFilter.PropertyType.GetGenericArguments()[0];
// get the definition of `Any` extension method from `Enumerable` class to make the expression
var anyMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public)
.First(x => x.Name == "Any" && x.GetParameters().Length == 2)
.MakeGenericMethod(entityFilterType);
// get a methodBase for GetFunc to get the delagete to use inside the Any
// using the `Document` generic type
var collectionBody = typeof(LookUpHelper).GetMethod("GetFunc", BindingFlags.Public | BindingFlags.Static)
.MakeGenericMethod(entityFilterType);
// call the any passing the collection I need and convert it to a Delegate
// I get something like: x => values.Contains(x.Id) ... where x if the `Document`
var func = (Delegate)collectionBody.Invoke(null, new object[] { values });
// get the func as an expression .. maybe the problem is here
var funcExpression = Expression.Constant(func);
// call the any passing the collection and my delagate as arguments
var f = Expression.Call(anyMethod, collectionPropertyExpression, funcExpression);
// I already have an expression and concatenate it using `AndAlso` operator.
body = Expression.AndAlso(body, f);
// finally, I built up to lambda expression and apply it on my queryable
var filterExpression = Expression.Lambda<Func<T, bool>>(body, parameter);
var result = Queryable.Where(filterExpression).ToList();
It executes until the query be executed by ToList method. I am getting the following error:
Could not parse expression
'x.Documents.Any(value(System.Func`2[Project.Document,System.Boolean]))':
The object of type 'System.Linq.Expressions.ConstantExpression' cannot
be converted to type 'System.Linq.Expressions.LambdaExpression'. If
you tried to pass a delegate instead of a LambdaExpression, this is
not supported because delegates are not parsable expressions.
I am not sure what I am doing wrong. Someone can help me?
Thank you.
You are passing a Func where an Expression<Func> is expected. The former is a delegate and the latter is an expression.
public static Expression<Func<T, bool>> GetFunc<T>(long[] values)
where T : Entity
{
return x => values.Contains(x.Id);
}
Now you forego needing to build the expression manually with your expression helper class since you already have the expression.

Convert a Func<T> to Expression<Func<T>> for a known T [duplicate]

Since we can:
Expression<Func<int, bool>> predicate = x => x > 5;
var result = Enumerable.Range(0,10).Where(predicate.Compile());
How can I:
Func<int,bool> predicate = x => x > 5;
Expression<Func<int,bool>> exp = predicate.Decompile();
That is, I want to get the corresponding Expression of the Func. Is it possible?
There is no magic Decompile() for a delegate instance, short of deconstructing the IL (perhaps with mono.cecil). If you want an expression tree, you'll have to start with an expression tree, so have Expression<Func<int, bool>> througout.
As an edge case, you can get basic method delegate information from the delegate's .Method (the MethodInfo) and .Target (the arg0) - however, for most scenarios involving a lambda or anonymous method this will point at the compiler-generate method on the capture class, so won't really help you much. It is pretty much limited to scenarios like:
Func<string,int> parse = int.Parse;
Pass the lambda to a method that accepts an Expression<> and the C# compiler will pass you an expression tree at runtime. However this only works if you pass the lambda directly, not if you try to pass a delegate instance created from a lambda.
var exp = Decompile(x => x > 5);
public Expression<Func<int, bool>> Decompile(Expression<Func<int, bool>> exp)
{
return exp;
}
The closest option I've found for decompiling a delegate instance is detailed in this blog post from Jean-Baptiste Evain who works on the Mono team. He uses the excellent Mono.Cecil project to decompile the IL into a custom AST, then he maps it as best as possible into LINQ expressions.
You can try to use my library:
https://github.com/ashmind/expressive
Though it may not work as is for results of Compile(), since it is a DynamicMethod and getting IL of it is not straightforward. If you implement your own IManagedMethod implementation for DynamicMethod, though, it should just work.
I plan to implement DynamicMethod adapters, but do not yet know when.
You can’t decompile the delegate, but you can certainly create a new expression tree that simply calls the delegate:
Func<int, bool> predicate = x => x > 5;
Expression<Func<int, bool>> exp = x => predicate(x);

Local variable and expression trees

I am learning expression trees in C#.
I am stuck now for a while:
string filterString = "ruby";
Expression<Func<string, bool>> expression = x => x == filterString;
How can I construct this expression by code? There is no sample how to capture a local variable. This one is easy:
Expression<Func<string, bool>> expression = x => x == "ruby";
This would be:
ParameterExpression stringParam = Expression.Parameter(typeof(string), "x");
Expression constant = Expression.Constant("ruby");
BinaryExpression equals = Expression.Equal(stringParam, constant);
Expression<Func<string, bool>> lambda1 =
Expression.Lambda<Func<string, bool>>(
equals,
new ParameterExpression[] { stringParam });
The debugger prints the following for (x => x == filterString) :
{x => (x ==
value(Predicate.Program+<>c__DisplayClass3).filterString)}
Thanks for shedding some light on this topic.
Capturing a local variable is actually performed by "hoisting" the local variable into an instance variable of a compiler-generated class. The C# compiler creates a new instance of the extra class at the appropriate time, and changes any access to the local variable into an access of the instance variable in the relevant instance.
So the expression tree then needs to be a field access within the instance - and the instance itself is provided via a ConstantExpression.
The simplest approach for working how to create expression trees is usually to create something similar in a lambda expression, then look at the generated code in Reflector, turning the optimization level down so that Reflector doesn't convert it back to lambda expressions.
This code wraps the expression in a closure Block that treats the local variable as a constant.
string filterString = "ruby";
var filterStringParam = Expression.Parameter(typeof(string), "filterString");
var stringParam = Expression.Parameter(typeof(string), "x");
var block = Expression.Block(
// Add a local variable.
new[] { filterStringParam },
// Assign a constant to the local variable: filterStringParam = filterString
Expression.Assign(filterStringParam, Expression.Constant(filterString, typeof(string))),
// Compare the parameter to the local variable
Expression.Equal(stringParam, filterStringParam));
var x = Expression.Lambda<Func<string, bool>>(block, stringParam).Compile();
An old question but I came to it when trying to do something similar building expressions for Linq-to-entities (L2E) In that case you cannot use Expression.Block as it cannot be parsed down to SQL.
Here is an explicit example following Jon's answer which would work with L2E. Create a helper class to contain the value of the filter:
class ExpressionScopedVariables
{
public String Value;
}
Build the tree thus:
var scope = new ExpressionScopedVariables { Value = filterString};
var filterStringExp = Expression.Constant(scope);
var getVariable = typeof(ExpressionScopedVariables).GetMember("Value")[0];
var access = Expression.MakeMemberAccess(filterStringExp, getVariable);
And then replace the constant in the original code with the member access expression:
BinaryExpression equals = Expression.Equal(stringParam, access);
Expression<Func<string, bool>> lambda1 =
Expression.Lambda<Func<string, bool>>(
equals,
new ParameterExpression[] { stringParam });

Categories