Подтвердить что ты не робот

Почему выражения С# LINQ должны заканчиваться Select или Group By Clause, где, как никакое такое ограничение в VB.Net

Поскольку мое название самоочевидно, я знаю, как его исправить, но почему это так в первую очередь?

Сценарий

Я написал код 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")

Это отлично работает и не дает ошибок

но одна и та же логика в С# терпит неудачу

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

//Code to populate list

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

Это дает ошибку

enter image description here

Почему это ограничение в С#? Что-то конкретное, что мне не хватает?

4b9b3361

Ответ 1

VB.NET и С# - разные языки, поэтому естественно, что синтаксис запроса LINQ тоже отличается: С# требует select s, а VB.NET - нет.

Microsoft документация требует, чтобы запрос синтаксиса запроса в С# заканчивался на select или group:

Выражение запроса должно начинаться с предложения from и должно заканчиваться предложением select или group. Между первым из предложения и последним предложением select или group он может содержать одно или несколько из следующих необязательных предложений: where, orderby, join, let и даже extra from clauses. Вы также можете использовать ключевое слово для включения результата предложения join или group, чтобы служить источником дополнительных предложений в одном выражении запроса.

Подробнее о синтаксисе см. спецификацию языка С#, раздел 7.16.

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

Вам не нужно добавлять select, если вы используете синтаксис функции:

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

Ответ 2

На самом деле это называется вырожденным выбором. Это вам не нужно, когда вы используете лямбда-синтаксис, с которым компилируется запрос. Почему это ограничение требуется, я действительно не знаю. Вероятно, это некоторые ограничения, связанные с компилятором, которые действительно не должны быть там.

Ответ 3

Одна из причин заключается в том, что без предложения select возникли бы двусмысленности. В следующем примере, как компилятор узнает, фильтрует ли where false собак или кости?

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

Однако половина вашего вопроса все еще остается без ответа: как VB избегает таких двусмысленностей?

Ответ 4

Несмотря на то, что в случае вырожденного выбора Where() и Where().Select() должны возвращать эквивалентные коллекции логически, и, таким образом, предложение Select() выглядит излишне поверхностным, типы возврата могут быть разными. Возможно, что тип возврата Where() не предназначен для конечного использования, а для цепочки с дополнительными операциями запроса, такими как Select(). То есть вы не можете ничего использовать с возвращаемым значением Where(), кроме добавления операции Select(). Требование оканчиваться на select или group, С# накладывает меньше требований на провайдера LINQ в том смысле, что оно не требует, чтобы возвращаемое значение Where() было подходящим для конечного использования, и это обеспечивает большую гибкость в дизайн Where().