Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
248 views
in Technique[技术] by (71.8m points)

c# - Convert LambdaExpression to String, Including Values

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

is different from this:

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

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)

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.

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;
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I use these strings as keys for a cache.

It's incorrect in a lot of circumstances, even it works in your project. Using Expression.ToString() as keys can be defeated easily by:

//counter-example 1
Expression<Func<string, bool>> exp1 = s => s == "a";
Expression<Func<string, bool>> exp2 = ss => ss == "a";
//the two will be considered different in your cache solution
//but they are essentially the same, well that's not the worst, see next

//counter-example 2
Expression<Func<int, bool>> exp3 = i => i > 10;
Expression<Func<long, bool>> exp4 = i => i > 10;
//the two will be considered the same in your cache solution
//of course they are different, probably hences runtime exceptions

The above is not an answer at all. If you don't care about that, let's continue based on "using strings as keys".

You want to cache the expressions, but identify those look-same expressions with constants in them. Then why not build the key with expression+constant? In your example code, the keys will be:

"m => m.P == p @@SPECIAL_SEPERATOR@@ x"
"m => m.P == p @@SPECIAL_SEPERATOR@@ y"

and yes, if one constant contains values like "@@SPECIAL_SEPERATOR@@", everything is going to crash. This is not a rigorous solution from the very beginning, because you choose strings as the cache key.

If you decide to choose another cache approach, check this.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...