LINQ select( x => x ) 的可能目的是什么?

13

我正在从一本MVC书籍中学习一些LINQ示例,并且我想知道下面的select调用可能有什么目的。也许这是一个打字错误,但我在书的勘误表中没有看到任何提到它的地方。

foreach( Product p in products
    .Where( e => e.Name == productParam.Name )
    .Select( e => e ) ) {
        p.Price = productParam.Price;
}

我测试了两个例子,一个包含了 .Select( e => e),另一个不包含,但代码是一样的。由于 Where 返回 IEnumerable 的过滤结果,那么何时需要使用带有上述特定谓词的 select 调用呢?它实际上是否起到作用?在某些奇怪的边缘情况下可能会吗?


我能想到的唯一可能是如果你明确定义了泛型参数并且返回值是从源代码中隐式可转换的值。您也可以合理地为调试包括断点(尽管您可能需要使用大括号和新行)。但除此之外(特别是因为您发布的代码中实际上都没有发生这两种情况),我无法想到任何有价值的目的。也许是从Linq查询语法中进行懒惰转换? - Chris Sinclair
这实际上是一个常见的错误。更常见的是在所有东西上都使用ToList。人们通常并不完全理解LINQ查询的执行模型(这是可以理解的)。 - usr
@usr 我真希望有一个(标准的)Force扩展,因为有很多时候必须强制评估IQuerable/IEnumerable,即使你并不真正对列表感兴趣。这个名称也会更明显地显示所需的操作。 - user166390
3个回答

13

1
不完全相同——它将返回IQueryable<T>。但除此之外,您是正确的,与没有Select表达式时得到的结果相同。 - chris
1
根据Enumerable.Select参考页面上的定义:“将序列的每个元素投影到一个新形式中。”以及投影是完全相同的形式,这似乎证明它在这里没有任何作用。 - seangwright
如果products是一个IQueryable,在大多数提供程序上,select调用将以O(1)结束,因为它什么也不做。 <-- 这只是挑刺而已。你的回答很好,我投了赞成票。 - usr
我的观点是它正在调用 lambda 表达式 e => e n 次。 - Daniel Imms
2
@DanielImms IQueryable提供程序通常不会调用lambda表达式(根本不会!它甚至不能执行。它是一个“Expression”)。它们会将其转换为SQL。 - usr

7

它实际上有用吗?

它会增加整个操作的开销。事实上,应该将其删除,因为它没有任何有用的目的。


3
我认为作者只是想展示LINQ查询与SQL语句非常相似。在这种情况下,由于使用了身份函数,因此显然不需要它,但是在SQL中必须有select子句。在那里有它并没有错,但绝对不需要。
尽管通常情况下,拥有一个身份选择调用并不总是一件坏事,特别是如果查询在函数中返回。这可以帮助您获得要返回的集合的只读视图。但是,在这种情况下,查询立即枚举,所以并不适用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接