I am dynamically creating a Lambda expression (based on user input but at the moment using dummy values for a proof-of-concept) for a type which I will only know at runtime. I therefore need to pass the T portion of the Func<T,TResult> as a dynamic type, since I won’t know the type until runtime (TResult will always be a bool).
It seems that I cannot pass in a Type variable or use typeof with generics. Basically I’m trying to do something like this:
// (f => f.Baz == 1)
Type theType = Type.GetType("Foo");
ParameterExpression pe = Expression.Parameter(theType, "f");
Expression left = Expression.Property(pe, theType.GetProperty("Baz"));
Expression right = Expression.Constant(1);
Expression expr = Expression.Equal(left, right);
// This works fine but uses a hard-coded type, which I won't know until runtime:
// var lambda = Expression.Lambda<Func<Foo,bool>>(expr, new ParameterExpression[] { pe }).Compile();
var lambda = Expression.Lambda<Func<theType, bool>>(expr, new ParameterExpression[] { pe }).Compile();
However, I cannot use the variable theType as the T portion of the Func. How can I fix this?
No you can’t.
For example, in C#, you can’t:
or
Unless you use reflection, but then you have to put the list in an
object, and you can use it only through reflection.So if you want you can save your
Func<>in anobject(or adynamic) but nothing more.What you COULD do is always return
Func<object, bool>and cast the object to the desidered type IN the lambda function (so use aExpression.Convert(pe, theType));Or you could use the dynamic:
or
To be taken “not as real” some benchmarks (in StopWatch.Ticks, look at them only for proportions) (Release Mode + Start Without Debugging + some useless cycles so that they are “hot”):
as a note,
Func<Foo, bool>has the same speed, so there isn’t any speed lost in the extra cast.You can see the code here http://ideone.com/qhnVP3