12

由于我的标题是不言自明的,我知道如何纠正它,但为什么会这样呢?

设想

我写了一个 VB.Net 代码

Dim list As List(Of String) = New List(Of String)

//Code to populate list

Dim wherelinq As IEnumerable(Of String) = From s In list Where s.StartsWith("A")

这工作正常,没有错误

但 C# 中的相同逻辑失败

List<string> list = new List<string>();

//Code to populate list

IEnumerable<string> wherelinq = from s in list where s.StartsWith("A");

这给出了错误

在此处输入图像描述

为什么在 C# 中有这个限制?我缺少什么具体的东西吗?

4

4 回答 4

5

VB.NET 和 C# 是不同的语言,因此 LINQ 查询语法自然也不同:C# 需要select s,而 VB.NET 不需要。

Microsoft 的文档要求 C# 中的查询语法查询必须以selector结尾group

查询表达式必须以 from 子句开头,并且必须以 select 或 group 子句结尾。在第一个 from 子句和最后一个 select 或 group 子句之间,它可以包含一个或多个这些可选子句:where、orderby、join、let 甚至附加 from 子句。您还可以使用 into 关键字来启用连接或组子句的结果作为同一查询表达式中其他查询子句的源。

有关语法的详细信息,请参阅 C# 语言规范,第 7.16 节。

var wherelinq = from s in list where s.StartsWith("A") select s;

select如果使用函数语法,则不必添加:

var wherelinq = list.Where(s => s.StartsWith("A"));
于 2012-10-20T12:42:25.083 回答
4

这实际上称为退化选择。当您使用查询编译成的 lambda 语法时,您不需要它。为什么需要这个限制,我真的不知道。这些可能是一些与编译器相关的限制,实际上不必存在。

于 2012-10-20T23:30:14.903 回答
-2

一个原因是,如果没有该select条款,就会有歧义。在以下示例中,编译器如何知道where false过滤器是狗还是骨头?

from dog in dogs
let gifts = from bone in bones
            where false

但是,您的一半问题仍未得到解答:VB 如何避免这种歧义?

于 2012-10-20T14:04:39.173 回答
-2

尽管在退化的选择情况下,Where()并且Where().Select()应该在逻辑上返回等效的集合,从而使Select()子句在表面上看起来是多余的,但返回类型可能不同。可能的返回类型Where()不是用于最终用途,而是用于与其他查询操作(如Select(). 也就是说,Where()除了附加Select()操作之外,您可能不会对 的返回值做任何有用的事情。通过要求以selector结尾group,C# 对 LINQ 提供程序的要求更少,因为它不需要返回值Where()适合最终使用,这允许Where().

于 2016-04-14T09:44:04.127 回答