Примечание. Мне известно о более раннем вопросе "Какова цель метода LINQ Expression.Quote?" , но если вы читайте дальше, вы увидите, что он не отвечает на мой вопрос.
Я понимаю, что заявленная цель Expression.Quote(). Тем не менее, Expression.Constant() может использоваться для той же цели (в дополнение ко всем целям, для которых Expression.Constant() уже используется). Поэтому я не понимаю, почему Expression.Quote() вообще требуется.
Чтобы продемонстрировать это, я написал быстрый пример, в котором обычно используется Quote (см. строку, помеченную восклицательными знаками), но вместо этого я использовал Constant, и он работал одинаково хорошо:
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);
Вывод expr.ToString() одинаковый для обоих, тоже (использую ли я Constant или Quote).
Учитывая приведенные выше наблюдения, оказывается, что Expression.Quote() является избыточным. Компилятор С# мог бы быть создан для компиляции вложенных лямбда-выражений в дерево выражений с использованием Expression.Constant() вместо Expression.Quote(), и любой поставщик запросов LINQ, который хочет обработать деревья выражений на каком-то другом языке запросов (например, SQL), может выглядеть для ConstantExpression с типом Expression<TDelegate> вместо UnaryExpression со специальным типом Quote node, а все остальное будет одинаковым.
Что мне не хватает? Почему Expression.Quote() и специальный Quote node тип для UnaryExpression изобрел?