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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…