如何在不使用Compile()的情况下实现这一目标,但只能使用正常反射?
var value = Expression.Lambda(memberExpression).Compile().DynamicInvoke();
我希望能够在IPhone(MonoTouch)上运行,但不允许进行动态编译。
更新:这里有更多背景信息。这是我正在处理的代码:
if (expression.Expression is ConstantExpression)
{
var constantExpression = (ConstantExpression)expression.Expression;
var fieldInfo = constantExpression.Value.GetType().GetField(expression.Member.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (fieldInfo != null)
{
return fieldInfo.GetValue(constantExpression.Value);
}
{
var propertyInfo = constantExpression.Value.GetType().GetProperty(expression.Member.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (propertyInfo != null)
{
return propertyInfo.GetValue(constantExpression.Value, null);
}
}
}
else
{
return Expression.Lambda(expression.Expression).Compile().DynamicInvoke();
}
如您所见,if块中的代码不使用运行时编译来获取值。我的目标是使用else块而不是中的代码使用运行时编译。
答案 0 :(得分:4)
你做不到。反射是元数据工具和非常有限字节代码检查。它不允许突变或代码生成。从根本上说,您在这里要实现的是元数据和IL生成行为。反射不适用于这种情况。
答案 1 :(得分:0)
我有一些更具体的案例:
private static object ExtractValue(Expression expression)
{
if (expression == null)
{
return null;
}
var ce = expression as ConstantExpression;
if (ce != null)
{
return ce.Value;
}
var ma = expression as MemberExpression;
if (ma != null)
{
var se = ma.Expression;
object val = null;
if (se != null)
{
val = ExtractValue(se);
}
var fi = ma.Member as FieldInfo;
if (fi != null)
{
return fi.GetValue(val);
}
else
{
var pi = ma.Member as PropertyInfo;
if (pi != null)
{
return pi.GetValue(val);
}
}
}
var mce = expression as MethodCallExpression;
if (mce != null)
{
return mce.Method.Invoke(ExtractValue(mce.Object), mce.Arguments.Select(ExtractValue).ToArray());
}
var le = expression as LambdaExpression;
if (le != null)
{
if (le.Parameters.Count == 0)
{
return ExtractValue(le.Body);
}
else
{
return le.Compile().DynamicInvoke();
}
}
var dynamicInvoke = Expression.Lambda(expression).Compile().DynamicInvoke();
return dynamicInvoke;
}
可能存在具有更复杂表达式的库(新对象创建等)。