.net 查看lambda/表达式树内部

.net 查看lambda/表达式树内部,.net,reflection,c#-4.0,lambda,.net,Reflection,C# 4.0,Lambda,给定以下任一变量,我如何“检查”它们以获得传入的参数值?i、 e.12345 System.Func<DateTime> f1 = () => DateTime.Now.AddDays(12345); System.Linq.Expressions.Expression<System.Func<DateTime>> f2 = () => DateTime.Now.AddDays(12345); Sy

给定以下任一变量,我如何“检查”它们以获得传入的参数值?i、 e.12345

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

System.Linq.Expressions.Expression<System.Func<DateTime>> 
                      f2 = () => DateTime.Now.AddDays(12345);
System.Func f1=()=>DateTime.Now.AddDays(12345);
System.Linq.Expressions.Expression
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);
var天数=123;
var小时数=456;
System.Func f1=()=>DateTime.Now.AddDays(天).AddHours(小时);
表达式f2=()=>DateTime.Now.AddDays(天).AddHours(小时);
我真正想要的是一种在给定lamda表达式的情况下生成单键“key”的方法。
我的想法是使用方法名和参数名/值对,但欢迎您提出其他建议!谢谢。

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

int days = (f1() - DateTime.Now).Days;
我怀疑这是你想要的

但是,如果函数体的定义与您的示例一样清晰,那么从f2获取值是可能的,也不是那么困难。它将启动类似于
(f2作为LambdaExpression.Body作为MethodCallExpression)…


我可能要花很长时间才能弄清楚确切的过程,但如果您只在调试器中检查f2,可能会更容易。

我能看到的从f1获取它的唯一方法是:

int days = (f1() - DateTime.Now).Days;
我怀疑这是你想要的

但是,如果函数体的定义与您的示例一样清晰,那么从f2获取值是可能的,也不是那么困难。它将启动类似于
(f2作为LambdaExpression.Body作为MethodCallExpression)…


我可能要花很长时间才能弄清楚确切的过程,但如果您只在调试器中检查f2,可能会更容易。

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

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

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

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

作为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();
    }
public void Run()
{
System.Linq.Expressions.Expression f2=()=>DateTime.Now.AddDays(12345);
MethodCallExpression调用=(MethodCallExpression)f2.Body;
ConstantExpression arg=(ConstantExpression)call.Arguments[0];
var值=GetValue(arg);
Debug.WriteLine(值);
}
私有对象GetValue(ConstantExpression表达式)
{
表达式转换=表达式.Convert(表达式,typeof(对象));
var getterLambda=Expression.Lambda(转换);
var getter=getterLambda.Compile();
返回getter();
}

作为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();
    }
public void Run()
{
System.Linq.Expressions.Expression f2=()=>DateTime.Now.AddDays(12345);
MethodCallExpression调用=(MethodCallExpression)f2.Body;
ConstantExpression arg=(ConstantExpression)call.Arguments[0];
var值=GetValue(arg);
Debug.WriteLine(值);
}
私有对象GetValue(ConstantExpression表达式)
{
表达式转换=表达式.Convert(表达式,typeof(对象));
var getterLambda=Expression.Lambda(转换);
var getter=getterLambda.Compile();
返回getter();
}

f1
确实包含信息,但仅通过检查C#编译器生成的IL<代码>f2如果执行,则在运行时编译,C#编译器只会创建一个表达式树,您可以使用
表达式
类型和子类型进行检查。
f1
确实包含信息,但仅通过检查C#编译器生成的IL<代码>f2如果执行,将在运行时编译,C#编译器只会创建一个表达式树,您可以使用
表达式
类型和子类型检查它。