注意: 我知道前面的问题“ 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()
是多余的。C # 编译器可以将嵌套的 lambda 表达式编译成一个包含 Expression.Constant()
而不是 Expression.Quote()
的表达式树,任何想要将表达式树处理成其他查询语言(如 SQL)的 LINQ 查询提供程序都可以寻找 Expression<TDelegate>
类型的 ConstantExpression
而不是 Quote
特殊节点类型的 UnaryExpression
,其他一切都是一样的。
我错过了什么? 为什么是 Expression.Quote()
和特殊的 Quote
节点类型为 UnaryExpression
发明?