#c# #.net #linq #reflection
#c# #.net #linq #отражение
Вопрос:
Я пишу некоторый код для анализа выражений, который должен получить доступ к значению параметров в 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;
}
Ответ №1:
Объект, содержащий значение вашего поля, содержится в Expression
свойстве parameterExpression
. Таким образом, измените предпоследнюю строку вашего кода на:
object fieldValue = parameterFieldInfo.GetValue(
((ConstantExpression)parameterExpression.Expression).Value);
Экземпляр, который мы передаем, является типом constant closure, доступным через parameterExpression
.
Вот .Чистая скрипка, демонстрирующая решение.