get end values from lambda expressions method parameters

后端 未结 5 1261
青春惊慌失措
青春惊慌失措 2020-12-10 15:48

basically I want to get the values of the parameters of a called method like this:

var x = 1;
var a = 2;
var b = 3;
Do(o => o.Save(x         


        
5条回答
  •  盖世英雄少女心
    2020-12-10 16:21

    Here is some code that is designed to work with any expression — in the sense that it doesn’t fundamentally assume that you are passing in a method-call expression. However, it is not complete. You will have to fill in the rest.

    public static IEnumerable ExtractConstants(
            Expression> expression)
    {
        return extractConstants(expression);
    }
    private static IEnumerable extractConstants(Expression expression)
    {
        if (expression == null)
            yield break;
    
        if (expression is ConstantExpression)
            yield return ((ConstantExpression) expression).Value;
    
        else if (expression is LambdaExpression)
            foreach (var constant in extractConstants(
                    ((LambdaExpression) expression).Body))
                yield return constant;
    
        else if (expression is UnaryExpression)
            foreach (var constant in extractConstants(
                    ((UnaryExpression) expression).Operand))
                yield return constant;
    
        else if (expression is MethodCallExpression)
        {
            foreach (var arg in ((MethodCallExpression) expression).Arguments)
                foreach (var constant in extractConstants(arg))
                    yield return constant;
            foreach (var constant in extractConstants(
                    ((MethodCallExpression) expression).Object))
                yield return constant;
        }
    
        else
            throw new NotImplementedException();
    }
    
    
    

    For the case that you have mentioned, this already works:

    // Prints:
    // Jimmy (System.String)
    // 1 (System.Int32)
    foreach (var constant in Ext.ExtractConstants(
            str => Console.WriteLine("Jimmy", 1)))
        Console.WriteLine("{0} ({1})", constant.ToString(),
                                       constant.GetType().FullName);
    

    For more complex lambda expressions that employ other types of expression nodes, you will have to incrementally extend the above code. Every time you use it and it throws a NotImplementedException, here is what I do:

    • Open the Watch window in the debugger
    • Look at the expression variable and its type
    • Add the necessary code to handle that expression type

    Over time the method will become more and more complete.

    提交回复
    热议问题