Почему выражения С# 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]()
Почему это ограничение в С#? Что-то конкретное, что мне не хватает?
Ответы
Ответ 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()
.