2009-10-06 1 views
4

Как я могу достичь этого без использования Compile(), но только с нормальным отражением?Отражение против компиляции, чтобы получить значение MemberExpression

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

Как вы можете видеть, код в блоке, если не использует во время выполнения компиляции для получения значения. Моя цель состоит в том, что код в блоке else не используется.

ответ

4

Вы не можете. Отражение - инструмент для метаданных и очень ограниченный байт проверка кода. Он не допускает мутации или генерации кода. В основном то, что вы пытаетесь достичь здесь, - это метаданные и акт генерации IL. Отражение не будет работать для этого сценария.

+0

Что вы говорите не совсем правильно. Я знаю, например, что в случае, когда выражение memberExpression.Expression является константным выражением, вы можете получить его значение, отразившись на свойстве Value значения константы. Моя проблема в том, что, когда это не ConstantExpression, я не могу понять, как получить дескриптор экземпляра, который содержит значение. –

+0

Если это не константа, вам нужно выполнить ее, чтобы получить результат. Таким образом, компиляция. – 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; 
    } 

Может быть есть библиотека с более сложными выражениями (новый объект творчества и т.д.).