不使用LinQ查询语法调用Select方法
我想在我的类上启用LinQ查询语法。 我认为查询语法被转换为方法语法,例如:
var query = from p in new Class1() where p.Id == "1000" select p
被翻译成:
var query = new Class1().Where(p => p.Id == "1000").Select(p => p);
然后我将Class1
实现为:
public class Class1 { public Class1 Where(Expression<Func> expression) { return this; } public Class1 Select(Func expression) { return this; } }
我用这段代码测试了它:
static void Main(string[] args) { var query = from p in new Class1() where p.Id == "1000" select p; }
然后我注意到没有调用Select
方法,但是如果我删除了来自LinQ Select
clausule被调用:
static void Main(string[] args) { var query = from p in new Class1() // where p.Id == "1000" -> commenting that Select method is called select p; }
有人知道为什么吗?
这里有一个小提琴,你可以测试它: https : //dotnetfiddle.net/JgxKG9
有人知道为什么吗?
是的,因为这就是语言规范所要做的。 查询表达式转换全部在C#5规范的7.16.2节中。
第7.16.2.5节解释了为什么您的初始示例不正确 – 不会调用Select
:
表单的查询表达式
from x in e select v
被翻译成
( e ) . Select ( x => v )
除非v是标识符
x
,否则翻译很简单( e )
例如
from c in customers.Where(c => c.City == “London”) select c
简单地翻译成
customers.Where(c => c.City == “London”)
但是,7.16.2.3中涵盖的退化查询表达式不是这种情况 – 这解释了删除where
子句时会发生什么:
表单的查询表达式
from x in e select x
被翻译成
( e ) . Select ( x => x )
这个例子
from c in customers select c
被翻译成
customers.Select(c => c)
简并查询表达式是一种简单地选择源元素的表达式 。 翻译的后期阶段通过用其源替换它们来移除由其他翻译步骤引入的简并查询。 但是,重要的是要确保查询表达式的结果永远不是源对象本身,因为这会向查询的客户端显示源的类型和标识。 因此,此步骤通过在源上显式调用Select来保护直接在源代码中编写的简并查询。 然后由
Select
和其他查询运算符的实现者来确保这些方法永远不会返回源对象本身。
您的理解有点不正确,以下查询:
var query = from p in new Class1() where p.Id == "1000" select p
将翻译为:
var query = new Class1().Where(p => p.Id == "1000");
当你删除where
部分时:
var query = from p in new Class1() select p;
现在它将被翻译成类似的东西:
var query = new Class1().Select(p=>p);
我很确定从查询语法到方法语法的转换会优先调用Select
away,如果它声明了身份投影 。
由于p => p
会将所有内容投射到自身,并且Where
子句已经在源序列和结果之间添加了一个抽象层,因此不再需要此调用。
所以
var query = from p in new Class1() where p.Id == "1000" select p;
只被翻译成
var query = new Class1().Where(p => p.Id == "1000");
但我承认我只是猜测,我仍然在寻找相关的规范部分。
更新:乔恩更快
上述就是C#学习教程:不使用LinQ查询语法调用Select方法分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/957712.html