Як працює наступний оператор LINQ ?
Ось мій код:
var list = new List<int>{1,2,4,5,6};
var even = list.Where(m => m%2 == 0);
list.Add(8);
foreach (var i in even)
{
Console.WriteLine(i);
}
Вихід: 2, 4, 6, 8
Чому ні 2, 4, 6
?
Як працює наступний оператор LINQ ?
Ось мій код:
var list = new List<int>{1,2,4,5,6};
var even = list.Where(m => m%2 == 0);
list.Add(8);
foreach (var i in even)
{
Console.WriteLine(i);
}
Вихід: 2, 4, 6, 8
Чому ні 2, 4, 6
?
Відповіді:
Вихід відбувається 2,4,6,8
через відкладене виконання .
Запит фактично виконується, коли змінна запиту переглянута, а не коли створена змінна запиту. Це називається відкладеним виконанням.
- Suprotim Agarwal, "Відкладений проти негайного виконання запитів у LINQ"
Існує ще одне виконання, яке називається негайне виконання запиту , яке корисно для кешування результатів запиту. Знов Супротим Агарвал:
Щоб примусити негайно виконати запит, який не видає однотонного значення, ви можете викликати
ToList(), ToDictionary(), ToArray(), Count(), Average()
абоMax()
метод на змінну запиту чи запиту. Це називаються операторами перетворення, які дозволяють зробити копію / знімок результату та отримати доступ стільки разів, скільки не потрібно повторно виконувати запит.
Якщо ви хочете, щоб результат був 2,4,6
, використовуйте .ToList()
:
var list = new List<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);
}
.First()
, .FirstOrDefault()
, .Single()
а .SingleOrDefault()
також викликати обчислення запиту.
Це сталося через відкладене виконання, а це означає, що обчислення виразу не виконується, поки воно не потрібно десь. Це робить ефективність кращою, якщо дані занадто великі.
Причиною цього є відкладене виконання вашого лямбда-виразу. Запит виконується, коли ви починаєте ітерацію в циклі foreach.
Ви отримуєте цей результат через відкладене виконання, тобто результат насправді не оцінюється до його першого доступу.
Щоб зробити це більш зрозумілим, просто додайте 10 до списку в кінці свого фрагмента, а потім знову надрукуйте, ви не отримаєте 10 у виводі
var list = new List<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
на виході.
8
жодного виводу.