gpt4 book ai didi

c# - 为什么这个 LINQ 查询可以编译?

转载 作者:太空狗 更新时间:2023-10-29 22:07:39 26 4
gpt4 key购买 nike

在阅读了 Jon Skeet 的“Odd query expressions”之后,我尝试了下面的代码。我希望最后的 LINQ 查询转换为 int query = proxy.Where(x => x).Select(x => x); 不会编译,因为 Where 返回一个 int。代码编译并在屏幕上打印“Where(x => x)”,查询设置为 2。从不调用 Select,但它需要在那里才能编译代码。发生了什么事?

using System;
using System.Linq.Expressions;

public class LinqProxy
{
public Func<Expression<Func<string,string>>,int> Select { get; set; }
public Func<Expression<Func<string,string>>,int> Where { get; set; }
}

class Test
{
static void Main()
{
LinqProxy proxy = new LinqProxy();

proxy.Select = exp =>
{
Console.WriteLine("Select({0})", exp);
return 1;
};
proxy.Where = exp =>
{
Console.WriteLine("Where({0})", exp);
return 2;
};

int query = from x in proxy
where x
select x;
}
}

最佳答案

这是因为您的“select x”实际上是一个空操作——编译器不会费心将 Select(x => x) 调用放在最后。不过,如果您删除 where 子句,它。您当前的查询称为退化查询表达式。有关详细信息,请参阅 C# 4 规范的第 7.16.2.3 节。特别是:

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.

所以,三个翻译(不考虑数据源)

// Query                          // Translation
from x in proxy proxy.Where(x => x)
where x
select x


from x in proxy proxy.Select(x => x)
select x


from x in proxy proxy.Where(x => x)
where x .Select(x => x * 2)
select x * 2

关于c# - 为什么这个 LINQ 查询可以编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3834412/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com