代码之家  ›  专栏  ›  技术社区  ›  Tim Scott

反射与编译以获取MemberExpression的值

  •  4
  • Tim Scott  · 技术社区  · 17 年前

    如何在不使用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块中的代码不使用运行时编译来获取值。我的目标是使 不 也可以使用运行时编译。

    2 回复  |  直到 17 年前
        1
  •  4
  •   JaredPar    17 年前

    你不能。反射是元数据和 非常 有限字节码检查。它不允许突变或代码生成。从根本上讲,您试图实现的是元数据和IL生成行为。反射不适用于此场景。

        2
  •  0
  •   Vladimir    12 年前

    我有一些更具体的案例:

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

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