Как обновить глобальную переменную внутри условия `where` в LINQ? - PullRequest
0 голосов
/ 26 апреля 2019

Я хочу отфильтровать список, используя LINQ с методом расширения Where.Но помимо фильтрации я также хочу обновить глобальную переменную внутри Where.Однако я не могу этого сделать.Рассмотрим этот пример:

var list = new List<string> { "1", "2", "3", "4", "5" };

bool flag = false;
var newList = list.Where(item =>
{
    flag = true;
    return item == "2";
});

// Here I expect flag = true, but in fact it's false
Console.Write(flag);

Как видите, я установил flag = true, но все равно значение flag == false после выполнения.Это не имеет смысла для меня.Можете ли вы объяснить, что происходит под капотом и почему flag не изменилось.Также есть ли способ изменить глобальные переменные внутри LINQ вообще?

Ответы [ 2 ]

3 голосов
/ 26 апреля 2019

Просто позвоните ToArray() или ToList(), чтобы фактически выполнить код, который устанавливает flag:

var newList = list.Where(item =>
{
    flag = true;
    return item == "2";
}).ToArray();

Предикат, который вы передаете методу Where, не оценивается, пока список фактически не будет перечислен.

3 голосов
/ 26 апреля 2019

Linq-запросы являются ленивыми, поэтому до тех пор, пока вы не перечислите newList, вы не увидите изменений, потому что ваше местоположение не было выполнено.

var list = new List<string> { "1", "2", "3", "4", "5" };

bool flag = false;
var newList = list.Where(item =>
{
    flag = true;
    return item == "2";
});

Console.WriteLine(flag); // Flag is still false.

foreach (var item in newList) {
  // It doesn't matter what we do here, just that we enumerate the list.
}

Console.Write(flag); // Flag is now true.

Функция foreach вызывает выполнение where и устанавливает ваш флаг.

Я бы действительно советовал не использовать предикат where для создания побочного эффекта, кстати, но вы так и сделаете.

...