Note: I am aware of the earlier question “What is the purpose of LINQ's Expression.Quote method?”, but if you read on you will see that it doesn’t answer my question.
I understand what the stated purpose of Expression.Quote() is. However, Expression.Constant() can be used for the same purpose (in addition to all the purposes that Expression.Constant() is already used for). Therefore, I don’t understand why Expression.Quote() is at all required.
To demonstrate this, I have written a quick example where one would customarily use Quote (see the line marked with exclamation points), but I used Constant instead and it worked equally well:
string[] array = { "one", "two", "three" };
// This example constructs an expression tree equivalent to the lambda:
// str => str.AsQueryable().Any(ch => ch == 'e')
Expression<Func<char, bool>> innerLambda = ch => ch == 'e';
var str = Expression.Parameter(typeof(string), "str");
var expr =
Expression.Lambda<Func<string, bool>>(
Expression.Call(typeof(Queryable), "Any", new Type[] { typeof(char) },
Expression.Call(typeof(Queryable), "AsQueryable",
new Type[] { typeof(char) }, str),
// !!!
Expression.Constant(innerLambda) // <--- !!!
),
str
);
// Works like a charm (prints one and three)
foreach (var str in array.AsQueryable().Where(expr))
Console.WriteLine(str);
The output of expr.ToString() is the same for both, too (whether I use Constant or Quote).
Given the above observations, it appears that Expression.Quote() is redundant. The C# compiler could have been made to compile nested lambda expressions into an expression tree involving Expression.Constant() instead of Expression.Quote(), and any LINQ query provider that wants to process expression trees into some other query language (such as SQL) could look out for a ConstantExpression with type Expression<TDelegate> instead of a UnaryExpression with the special Quote node type, and everything else would be the same.
What am I missing? Why was Expression.Quote() and the special Quote node type for UnaryExpression invented?