Примечание. Мне известно о более раннем вопросе "Какова цель метода 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
изобрел?