views:

50

answers:

3

Given either of the variables below, how can I 'inspect' them to obtain the parameter value passed in? i.e. 12345.

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

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

Edit:

The two answers below by Mikael and Kirk both answer my orignal question. However, I've now made this a little more complex to deal with 'real life'. Ideally I'm looking for a 'general' solution, which will work with something alongs the lines of the below:

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);

What I'm really after is a way to generate a unikey 'key' given a lamda expression. My idea is to use the method name, and the parameter name/value pairs, but I'm welcome to other suggestions! Thanks.

+1  A: 

The only way I can see to get it from f1 is by:

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

which I doubt is what you want.

Getting the value from f2, however, is possible, and not that difficult, if the body of the function is as clearly defined as your example. It will start something like ((f2 as LambdaExpression).Body as MethodCallExpression)....

I could take a long time to figure out the exact process, but it would probably be easier, for you to just inspect f2 in the debugger.

James Curran
+2  A: 

If you mean the value 12345, that data is only available in f2. For f2:

MethodCallExpression call = (MethodCallExpression)f2.Body;
ConstantExpression arg = (ConstantExpression)call.Arguments[0];
Console.WriteLine(arg.Value);
Kirk Woll
+3  A: 

As an addition to Kirk Woll's answer, if you want to have the 12345 as an object, you can use the following:

    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();
    }
Mikael Koskinen