Как получить доступ к закрытой локальной переменной в MemberExpression?

1

Я пишу код анализа выражений, которому необходимо получить доступ к значению параметров в Expression<Action>.

Приведенный ниже код работает всякий раз, когда параметр является членом или свойством исходного объекта, но не работает, когда элемент является локальной локальной переменной. Как получить доступ к анонимному типу, который закрывается по локальной переменной, чтобы я мог получить доступ к локальной переменной?

Здесь появляется сообщение об ошибке:

Test method FluentCache.Test.ClosureTest.Test threw exception: 
System.ArgumentException: Field 'localVariable' defined on type 'Test.ClosureTest+<>c__DisplayClass2' is not a field on the target object which is of type 'Test.ClosureTest'

Здесь упрощенный код:

[TestMethod]
public void Test()
{
    Func<int, int> myAction = i => i + 1;
    int localVariable = 10;

    int analyzed = (int)GetFirstParameterValue(this, () => myAction(localVariable));

    Assert.AreEqual(localVariable, analyzed);
}

public object GetFirstParameterValue(object source, Expression<Action> expression)
{
    var invocationExpression = expression.Body as InvocationExpression;
    var parameterExpression = invocationExpression.Arguments[0] as MemberExpression;
    var parameterFieldInfo = parameterExpression.Member as FieldInfo;

    //ERROR: This code will fail because the local variable is "wrapped" in a closure anonymous type
    //How do I get access to the anonymous type in order to retrieve the value?
    object fieldValue = parameterFieldInfo.GetValue(source);
    return fieldValue;
}
Теги:
linq
reflection

1 ответ

1
Лучший ответ

Объект, содержащий значение вашего поля, содержится в свойстве Expression parameterExpression. Таким образом, измените вторую на последнюю строку своего кода на:

object fieldValue = parameterFieldInfo.GetValue(
    ((ConstantExpression)parameterExpression.Expression).Value);

Экземпляр, который мы передаем, является типом постоянного закрытия, доступным через parameterExpression.

Здесь сценарий.Net демонстрирует решение.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню