将LambdaExpression转换为包含值的字符串 [英] Convert LambdaExpression to String, Including Values

查看:131
本文介绍了将LambdaExpression转换为包含值的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个将LambdaExpression转换为字符串的方法.我将这些字符串用作缓存的键.

I have a method which converts a LambdaExpression to a string. I use these strings as keys for a cache.

string p = "x";
var a = LambdaToString<MyType>(m => m.P == p);

与此不同:

string p = "y";
var a = LambdaToString<MyType>(m => m.P == p);

但是,无论p的值如何,我的LambdaToString方法的当前状态都会产生相同的输出.这是:

However, the current state of my LambdaToString method is producing the same output regardless of the value of p. Which is:

(MyType.P == value(ConsoleApplication1.Program+<>c__DisplayClass0).p)

我希望我的LambdaToString函数执行的操作是将表达式的"value(class).p"部分解析为实际的文字字符串"x"或"y"(视具体情况而定).

What I would like my LambdaToString function to do is to resolve the "value(class).p" portion of the expression into the actual literal string of "x" or "y" as the case may be.

这是我的LambdaToString方法的当前状态.我不确定要修改它以产生所需的输出将需要做什么:

Here is the current state of my LambdaToString method. I am not sure what I would need to do to modify it to produce the outputs I want:

    public static string LambdaToString<T>(Expression<Func<T, bool>> expression)
    {
        string body = expression.Body.ToString();

        foreach (var parm in expression.Parameters)
        {
            var parmName = parm.Name;
            var parmTypeName = parm.Type.Name;
            body = body.Replace(parmName + ".", parmTypeName + ".");
        }

        return body;
    }

推荐答案

这是我的答案.理想情况下,它将能够处理抛出的任何可能的Expression.现在它很可能没有,但是它处理了我在测试中扔给它的所有简单,常见的东西.

Here is my answer. Ideally this would be able to handle any possible Expression that is thrown at it. Right now it most likely does not, but it handled all the simple, common things I threw at it in my tests.

如果您提出的示例无法解决,请将其保留在注释中,我将尝试修改该函数以进行处理.

If you come up with an example this doesn't handle, leave it in the comments and I will try to modify the function to handle it.

    public static string LambdaToString<T>(Expression<Func<T, bool>> expression)
    {

        var replacements = new Dictionary<string, string>();
        WalkExpression(replacements, expression);


        string body = expression.Body.ToString();

        foreach (var parm in expression.Parameters)
        {
            var parmName = parm.Name;
            var parmTypeName = parm.Type.Name;
            body = body.Replace(parmName + ".", parmTypeName + ".");
        }

        foreach (var replacement in replacements)
        {
            body = body.Replace(replacement.Key, replacement.Value);    
        }

        return body;
    }

    private static void WalkExpression(Dictionary<string, string> replacements, Expression expression)
    {
        switch (expression.NodeType)
        {
            case ExpressionType.MemberAccess:
                string replacementExpression = expression.ToString();
                if (replacementExpression.Contains("value("))
                {
                    string replacementValue = Expression.Lambda(expression).Compile().DynamicInvoke().ToString();
                    if (!replacements.ContainsKey(replacementExpression))
                    {
                        replacements.Add(replacementExpression, replacementValue.ToString());
                    }
                }
                break;

            case ExpressionType.GreaterThan:
            case ExpressionType.GreaterThanOrEqual:
            case ExpressionType.LessThan:
            case ExpressionType.LessThanOrEqual:
            case ExpressionType.OrElse:
            case ExpressionType.AndAlso:
            case ExpressionType.Equal:
                var bexp = expression as BinaryExpression;
                WalkExpression(replacements, bexp.Left);
                WalkExpression(replacements, bexp.Right);
                break;

            case ExpressionType.Call:
                var mcexp = expression as MethodCallExpression;
                foreach (var argument in mcexp.Arguments)
                {
                    WalkExpression(replacements, argument);
                }
                break;

            case ExpressionType.Lambda:
                var lexp = expression as LambdaExpression;
                WalkExpression(replacements, lexp.Body);
                break;

            case ExpressionType.Constant:
                //do nothing
                break;

            default:
                Trace.WriteLine("Unknown type");
                break;
        }

这篇关于将LambdaExpression转换为包含值的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆