反射和编译获取MemberExpression的值

4
我如何在不使用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块中的代码也不使用运行时编译。

2个回答

4

您无法做到这一点。反射是元数据和非常有限的字节码检查工具。它不允许进行突变或代码生成。从根本上讲,您在此处尝试实现的是元数据和IL生成操作。反射对于此场景将无法使用。


你说的并不完全正确。例如,我知道在memberExpression.Expression是ConstantExpression的情况下,可以通过反射常量表达式的Value属性来获取其值。我的问题是,当它不是ConstantExpression时,我无法弄清楚如何处理持有该值的实例。 - Tim Scott
如果它不是一个常量,你需要执行它才能得到结果。因此需要编译。 - Gregory

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;
    }

可能有一些包含更复杂表达式(如新对象创建等)的库。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接