如何在MemberExpression中访问封闭的局部变量?

时间:2014-06-18 01:20:12

标签: c# .net linq reflection

我正在编写一些表达式来分析需要访问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 个答案:

答案 0 :(得分:1)

包含字段值的对象包含在Expression的{​​{1}}属性中。因此,将代码的倒数第二行更改为:

parameterExpression

我们传入的实例是通过object fieldValue = parameterFieldInfo.GetValue( ((ConstantExpression)parameterExpression.Expression).Value); 提供的常量闭包类型。

Here's a .Net fiddle展示了解决方案。