Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么C LINQ表达式必须以Select或Group By子句结尾,而VB.Net中没有这样的限制_C#_Vb.net_Linq - Fatal编程技术网

C# 为什么C LINQ表达式必须以Select或Group By子句结尾,而VB.Net中没有这样的限制

C# 为什么C LINQ表达式必须以Select或Group By子句结尾,而VB.Net中没有这样的限制,c#,vb.net,linq,C#,Vb.net,Linq,由于我的标题是不言自明的,我知道如何纠正它,但为什么它是在第一位呢 情景 我写了一个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>

由于我的标题是不言自明的,我知道如何纠正它,但为什么它是在第一位呢

情景

我写了一个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语言中有这样的限制?我缺少的任何具体内容?

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

Microsoft要求C中的查询语法查询必须以select或group结尾:

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

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

var wherelinq = from s in list where s.StartsWith("A") select s;
如果使用函数语法,则不必添加select:

var wherelinq = list.Where(s => s.StartsWith("A"));

一个原因是,如果没有select子句,就会出现歧义。在下面的示例中,编译器如何知道false在何处过滤狗或骨骼

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

然而,您的问题还有一半没有得到回答:VB如何避免这种歧义?

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

尽管在退化的select情况下,Where和Where.select应该在逻辑上返回等价的集合,从而使select子句表面上看起来多余,但返回类型可能不同。Where的返回类型可能不是用于最终用途,而是用于与其他查询操作(如Select)链接。也就是说,除了附加Select操作之外,您可能无法对Where的返回值执行任何有用的操作。通过要求以select或group结尾,C对LINQ提供程序的要求更少,因为它不要求Where的返回值适合最终使用,这使得Where的设计具有更大的灵活性。

您没有解释为什么C中会出现这种情况。除非没有其他解释,开发人员只是忘记了包含它。我已经说过我知道如何纠正它。但为什么会这样?@dasblinkenlight:谢谢你的链接。我在那里引用了一句话更新了你的答案-希望你不介意。@dasblinkenlight:谢谢。但从开发人员的角度考虑,为什么会这样。为什么他们必须保持两种不同的逻辑。一个用于C,另一个用于VB.Net?这些语言有什么不同吗?架构还是什么?我相信像Eric Lippert或Jon Skeet这样的人可以提供这些语言的内部视图。@NikhilAgrawal-如果你想知道我的猜测,这可以通过检查IL得到证实,VB.NET可能正在为你添加Select语句。VB经常添加隐式语言结构,而C则要求开发人员更加明确。只是两种不同的语言:不同的开发人员彼此喜爱。我们这里需要一些Eric Lippert。为什么会有歧义?VB.NET将选择一个匿名类型,该类型同时包含属性Dog和bone。