不使用LinQ查询语法调用Select方法 [英] Select method is not called using LinQ query syntax

查看:83
本文介绍了不使用LinQ查询语法调用Select方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想对我的类启用LinQ查询语法.我认为查询语法已转换为方法语法,例如:

I want to enable LinQ query syntax over my classes. I think query syntax is translated to method syntax, for example:

var query = from p in new Class1<Product>()
        where p.Id == "1000"
        select p

被翻译为:

var query = new Class1<Product>().Where(p => p.Id == "1000").Select(p => p);

然后我将Class1实现为:

public class Class1<T>
{
    public Class1<T> Where(Expression<Func<T, bool>> expression)
    {
        return this;
    }
    public Class1<T> Select<TResult>(Func<T, TResult> expression)
    {
        return this;
    }
}

我已经用以下代码对其进行了测试:

And I have tested it with this code:

static void Main(string[] args)
{
    var query = from p in new Class1<Product>()
                where p.Id == "1000"
                select p;
}

然后我注意到没有调用Select方法,但是,如果我从LinQ中删除where子句,则会调用Select:

Then I have noticed that Select method is not called, however if I remove where clausule from LinQ Select is called:

static void Main(string[] args)
{
    var query = from p in new Class1<Product>()
                // where p.Id == "1000" -> commenting that Select method is called
                select p;
}

有人知道为什么吗?

这里有一个小提琴,您可以在其中进行测试: https://dotnetfiddle.net/JgxKG9

Here a fiddle where you can test it: https://dotnetfiddle.net/JgxKG9

推荐答案

有人知道为什么吗?

Someone knows why?

是的,因为这就是语言规范所说的.查询表达式转换全部在C#5规范的7.16.2节中.

Yes, because that's what the language specification says to do. The query expression translation is all in section 7.16.2 of the C# 5 specification.

第7.16.2.5节说明了您最初的示例不正确的原因-Select不会被调用:

Section 7.16.2.5 explains why your initial example is incorrect - Select won't be called:

形式的查询表达式

A query expression of the form

from x in e select v

被翻译成

( e ) . Select ( x => v )

,除非 v 是标识符x,否则翻译简单

except when v is the identifier x, the translation is simply

( e )

例如

from c in customers.Where(c => c.City == "London")
select c

只是翻译成

customers.Where(c => c.City == "London")

但是,在7.16.2.3中涵盖的简并查询表达式并非如此-解释了删除where子句时会发生什么:

However, that isn't the case for degenerate query expressions which are covered in 7.16.2.3 - which explains what happens when you remove your where clause:

形式的查询表达式

A query expression of the form

from x in e select x

被翻译成

( e ) . Select ( x => x )

示例

from c in customers
select c

已翻译为

customers.Select(c => c)

一个简并查询表达式是一个简单地选择源元素的表达式.翻译的下一阶段通过将其他翻译步骤替换为源,从而消除了其他翻译步骤引入的简并查询.但是,重要的是要确保查询表达式的结果永远不会是源对象本身,因为这将向查询的客户端显示源的类型和身份.因此,此步骤通过在源上显式调用Select来保护直接用源代码编写的简并查询.然后,由Select的实现者和其他查询运算符来确保这些方法从不返回源对象本身.

A degenerate query expression is one that trivially selects the elements of the source. A later phase of the translation removes degenerate queries introduced by other translation steps by replacing them with their source. It is important however to ensure that the result of a query expression is never the source object itself, as that would reveal the type and identity of the source to the client of the query. Therefore this step protects degenerate queries written directly in source code by explicitly calling Select on the source. It is then up to the implementers of Select and other query operators to ensure that these methods never return the source object itself.

这篇关于不使用LinQ查询语法调用Select方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆