Результатом выражения запроса является запрос, а не его выполнение.
Эрик Липперт
6
Для получения дополнительной информации см. Принятый ответ на этот вопрос .
Даниэль
9
Конечно, вы можете придумать заголовок, который фактически суммирует вопрос.
Мэтт Болл
2
Мое предположение о отрицательных голосах (6 к настоящему времени, не мое) состоит в том, что они считают название вопроса слишком общим, чтобы быть хорошим вопросом. Но, учитывая количество голосов и становясь главным вопросом недели в новостной рассылке, я не думаю, что вам нужно слишком беспокоиться об этом.
Существует еще одно выполнение, называемое Immediate Query Execution , которое полезно для кэширования результатов запросов. Из Супротима снова Агарвал:
Чтобы принудительно выполнить запрос, который не выдает одноэлементное значение, можно вызвать метод ToList(), ToDictionary(), ToArray(), Count(), Average()или Max()для запроса или переменной запроса. Это так называемые операторы преобразования, которые позволяют вам сделать копию / снимок результата и получить доступ столько раз, сколько вам нужно, без необходимости повторного выполнения запроса.
Если вы хотите, чтобы вывод был 2,4,6, используйте .ToList():
varlist=newList<int>{1,2,4,5,6};var even =list.Where(m => m%2==0).ToList();list.Add(8);foreach(var i in even){Console.WriteLine(i);}
Count (), Max (), Avg (), Sum () и, возможно, другие методы, которые должны учитывать весь список, также вызывают оценку запроса.
Кенн
1
Я часто думал о том, чтобы, скажем, «FilterList» в качестве переменной, а не «FilterList ()» в качестве метода - идея заключается в том, что вы выполняете итерацию по нему каждый раз, когда хотите отфильтровать список, а не вызываете метод. Это может быть интересный, хотя и необычный и, возможно, несовершенный способ выполнения работы.
Katana314
4
@Sebastian - В дополнение к @ комментарий Kenned, в .First(), .FirstOrDefault(), .Single()а .SingleOrDefault()также вызвать вычисления запроса.
Scotty.NET
4
Удивительно, как вы получили ответ менее чем за 30 секунд: D
MC
2
@ MC Я не знаю, почему ты задаешь этот вопрос. Весь ответ не был дан за один раз. Он был отредактирован несколько раз.
Атиш Дипонгкор - MVP
11
Это произошло из-за отложенного выполнения, что означает, что вычисление выражения не выполняется, пока оно не понадобится где-то. Это повышает производительность, если данные слишком велики.
Вы можете нюансировать это, поскольку это также может означать, что ваше дорогостоящее перечисление выполняется несколько раз. В таком случае вы можете даже потерять производительность.
Гримаса Отчаяния
0
Причиной этого является отложенное выполнение вашего лямбда-выражения. Запрос выполняется, когда вы начинаете итерацию в цикле foreach.
Технически это отложенное выполнение итератора , а не лямбда .
D Стэнли
0
Когда вы используете IEnumerable <>, полученный из LINQ, создается только класс Enumerator, и итерация начинается только тогда, когда вы используете его в некоторой прогулке.
Вы получаете этот результат из-за отложенного выполнения, что означает, что результат фактически не оценивается до его первого доступа.
Чтобы сделать это более понятным, просто добавьте 10 к списку в конце вашего фрагмента и затем напечатайте снова, вы не получите 10 в выводе
varlist=newList<int>{1,2,4,5,6};var even =list.Where(m => m%2==0).Tolist();list.Add(8);foreach(var i in even){Console.WriteLine(i);}//new*list.Add(10);foreach(var i in even){Console.WriteLine(i);}
Вы действительно пробовали это? Я получаю 10в выходной.
Марк Херд
хороший улов @MarkHurd да не добавлено .ToList (). отредактировал пост, теперь он должен дать ожидаемый результат. Я ожидал, что выражение вычисляется только при первом использовании var, но похоже, что оно вычисляется каждый раз
sandeep
Теперь он не будет содержаться 8ни в одном выводе.
Ответы:
Выход
2,4,6,8
из-за отложенного выполнения .Существует еще одно выполнение, называемое Immediate Query Execution , которое полезно для кэширования результатов запросов. Из Супротима снова Агарвал:
Если вы хотите, чтобы вывод был
2,4,6
, используйте.ToList()
:источник
.First()
,.FirstOrDefault()
,.Single()
а.SingleOrDefault()
также вызвать вычисления запроса.Это произошло из-за отложенного выполнения, что означает, что вычисление выражения не выполняется, пока оно не понадобится где-то. Это повышает производительность, если данные слишком велики.
источник
Причиной этого является отложенное выполнение вашего лямбда-выражения. Запрос выполняется, когда вы начинаете итерацию в цикле foreach.
источник
Когда вы используете IEnumerable <>, полученный из LINQ, создается только класс Enumerator, и итерация начинается только тогда, когда вы используете его в некоторой прогулке.
источник
Вы получаете этот результат из-за отложенного выполнения, что означает, что результат фактически не оценивается до его первого доступа.
Чтобы сделать это более понятным, просто добавьте 10 к списку в конце вашего фрагмента и затем напечатайте снова, вы не получите 10 в выводе
источник
10
в выходной.8
ни в одном выводе.