在lambda /表达式树里面看

时间:2010-08-24 15:24:29

标签: .net reflection c#-4.0 lambda

鉴于下面的任何一个变量,我如何'检查'它们以获得传入的参数值?即12345。

System.Func<DateTime> f1 = () => DateTime.Now.AddDays(12345);

System.Linq.Expressions.Expression<System.Func<DateTime>> 
                      f2 = () => DateTime.Now.AddDays(12345);

编辑:

Mikael和Kirk在下面的两个答案都回答了我的问题。 但是,我现在对处理“现实生活”这个问题有点复杂了。 理想情况下,我正在寻找一种“通用”解决方案,它可以解决以下问题:

var days = 123;
var hours = 456;
System.Func<DateTime> f1 = () => DateTime.Now.AddDays(days).AddHours(hours);
Expression<System.Func<DateTime>> f2 = () => DateTime.Now.AddDays(days).AddHours(hours);

我真正想要的是一种在给定lamda表达式的情况下生成unikey'key'的方法。 我的想法是使用方法名称和参数名称/值对,但我欢迎其他建议!感谢。

3 个答案:

答案 0 :(得分:3)

作为Kirk Woll答案的补充,如果您想将12345作为对象,可以使用以下内容:

    public void Run()
    {
        System.Linq.Expressions.Expression<System.Func<DateTime>> f2 = () => DateTime.Now.AddDays(12345);

        MethodCallExpression call = (MethodCallExpression)f2.Body;
        ConstantExpression arg = (ConstantExpression)call.Arguments[0];

        var value = GetValue(arg);
        Debug.WriteLine(value);
    }

    private object GetValue(ConstantExpression expression)
    {
        Expression conversion = Expression.Convert(expression, typeof(object));
        var getterLambda = Expression.Lambda<Func<object>>(conversion);

        var getter = getterLambda.Compile();

        return getter();
    }

答案 1 :(得分:2)

如果您的意思是值12345,则该数据仅在 f2 中可用。对于f2:

MethodCallExpression call = (MethodCallExpression)f2.Body;
ConstantExpression arg = (ConstantExpression)call.Arguments[0];
Console.WriteLine(arg.Value);

答案 2 :(得分:1)

我能从f1获得它的唯一方法是:

int days = (f1() - DateTime.Now).Days;

我怀疑你想要什么。

然而,如果函数的主体与您的示例一样明确定义,那么从f2获取值是可能的,而不是那么困难。它将从((f2 as LambdaExpression).Body as MethodCallExpression)....

开始

我可能需要很长时间来弄清楚确切的过程,但是你可能更容易在调试器中检查f2。