I have a parameter of type object. Anything can be set on that parameter. And I need to find the property with a certain name in that parameter. If it exists of course.
I need something like this (pseudo code):
ParameterExpression arg = Expression.Parameter(parameter.GetType(), "x");
Expression expr = Expression.Property(arg, "Info");
var propertyResolver = Expression.Lambda<Func<parameter.GetType, object>>(expr, arg).Compile();
There is already the method `Expression.Lambda(Type, Expression, ...)
But that returns System.Delegate back to me and I need the Func<>.
What can I do to achieve this?
Thanks in advance guys.
Here is a demo:
class Program
{
private Func<object, object> func;
static void Main(string[] args)
{
// lets say in this case the parameter is person but it could be anything
Person parameter = new Person();
ParameterExpression arg = Expression.Parameter(parameter.GetType(), "x");
Expression expr = Expression.Property(arg, "Name");
var func = Expression.Lambda<Func<parameter.GetType, object>>(expr, arg).Compile();
}
}
class Person
{
public string Name { get; set; }
}
After I created my function I have to call it at least 1000 times in an for loop inside another method therefore DynamicInvoke is not an option here. Its too slow. I try it out.
Two options to consider:
Use dynamic typing to call a generic method which will return you a Func<object, object>
which you can use later by wrapping up an expression-tree-compiled delegate:
public Func<Object, Object> CreateFunc(object sampleValue)
{
dynamic dynamicValue = sampleValue;
return CreateFuncImpl(dynamicValue); // Dynamic type inference
}
private Func<Object, Object> CreateFuncImpl<T>(T sampleValue)
{
// You could use Delegate.CreateDelegate as another option -
// you don't need expression trees here
var parameter = Expression.Parameter(parameter.GetType(), "x");
var expression = Expression.Property(arg, "Name");
var func = Expression.Lambda<Func<T, object>>(expression, parameter)
.Compile();
return (object actualValue) => func((T) actualValue);
}
Wrap the property expression in a conversion expression in the expression tree:
public Func<Object, Object> CreateFunc(object sampleValue)
{
var parameter = Expression.Parameter(typeof(object), "x");
var conversion = Expression.Convert(parameter, sampleValue.GetType());
var property = Expression.Property(conversion, "Name");
return Expression.Lambda<Func<object, object>>(property, parameter)
.Compile();
}
Both of these assume that you're doing the creation very rarely and then calling the delegate many times with values of the same type. They may or may not be what you need - it's hard to tell with weak requirements. They do require that the values you call the function with later are of the right type, of course.
See more on this question at Stackoverflow