6 linq extension-methods delegates
将表达式传递给Linq查询的行为取决于所使用的语法,我想知道为什么会这样.
假设我有这个非常通用的功能
private IEnumerable<Company>
GetCompanies(Expression<Func<Company, bool>> whereClause)
Run Code Online (Sandbox Code Playgroud)
以下实现按预期工作
private IEnumerable<Company>
GetCompanies(Expression<Func<Company, bool>> whereClause)
{
return (from c in _ctx.Companies.Where(whereClause) select c);
}
Run Code Online (Sandbox Code Playgroud)
但是这个下一个实现不能编译(Delegate'System.Func'不带1个参数)
private IEnumerable<Company>
GetCompanies(Expression<Func<Company, bool>> whereClause)
{
return (from c in _ctx.Companies where whereClause select c);
}
Run Code Online (Sandbox Code Playgroud)
显然我可以使用第一种语法,但我只是想知道为什么编译器不会将where关键字视为Where扩展名?
谢谢,托马斯
涉及子句的查询表达式的语法where为(简化完整语法)
from identifier in expression where boolean-expression select expression
Run Code Online (Sandbox Code Playgroud)
whereClause不是布尔表达式。为了重申这一点,你必须说
from c in _ctx.Companies where whereClause.Compile()(c) select c;
Run Code Online (Sandbox Code Playgroud)
请注意,如果whereClause是 aFunc<Company, bool>你可以逃脱
from c in _ctx.Companies where whereClause(c) select c;
Run Code Online (Sandbox Code Playgroud)
注意
from x in e where f
Run Code Online (Sandbox Code Playgroud)
被编译器机械地翻译成
(from x in e).Where(x => f)
Run Code Online (Sandbox Code Playgroud)
我说机械地是因为它执行此转换,而不进行任何语义分析来检查方法调用的有效性等。在所有查询表达式都已转换为 LINQ 方法调用表达式之后,该阶段才会出现。
尤其,
from c in _ctx.Companies where whereClause select c
Run Code Online (Sandbox Code Playgroud)
被翻译成
_ctx.Companies.Where(c => whereClause).Select(c)
Run Code Online (Sandbox Code Playgroud)
这显然是荒谬的。
原因是
from c in _ctx.Companies.Where(whereClause) select c
Run Code Online (Sandbox Code Playgroud)
是合法的,因为IEnumerable<Company>.Where有一个接受 a 的重载Func<Company, bool>,并且存在从 anExpression<Func<Company, bool>>到 a 的隐式转换Func<Company, bool>。
| 归档时间: |
|
| 查看次数: |
743 次 |
| 最近记录: |