我有一个object类型的参数。可以在该参数上设置任何内容。我需要在该参数中找到具有特定名称的属性。如果它当然存在。
我需要这样的东西(伪代码):
ParameterExpression arg = Expression.Parameter(parameter.GetType(), "x");
Expression expr = Expression.Property(arg, "Info");
var propertyResolver = Expression.Lambda<Func<parameter.GetType, object>>(expr, arg).Compile();
已有方法`Expression.Lambda(Type,Expression,...)
但是这会将System.Delegate返回给我,我需要Func&lt;&gt;。
我能做些什么来实现这个目标?
先谢谢你们。
这是一个演示:
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; }
}
在我创建我的函数后,我必须在另一个方法中的for循环中至少调用1000次因此DynamicInvoke不是这里的选项。它太慢了。我试试看。
答案 0 :(得分:2)
需要考虑两个选项:
使用动态类型调用泛型方法,该方法将返回Func<object, object>
,稍后您可以通过包装表达式树编译的委托来使用该方法:
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);
}
将属性表达式包装在表达式树中的转换表达式中:
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();
}
这两个假设您很少进行创建,然后使用相同类型的值多次调用委托。它们可能是也可能不是你所需要的 - 很难用弱的要求来说明。他们确实要求稍后调用函数的值是正确的类型。
答案 1 :(得分:1)
也许这符合您的需求:
Expression.Lambda(Type, Expression, IEnumerable<ParameterExpression>)
.Compile()
.DynamicInvoke(...)