Проблема в том, что ваше лямбда-выражение захватывает переменную i
, но делегат не выполняется до окончания цикла.Ко времени выполнения выражения c != illegals[i]
значение i
равно illegals.Length
, поскольку это окончательное значение i
.Важно понимать, что лямбда-выражения захватывают переменные, а не «значения этих переменных в точке, где лямбда-выражение преобразуется в делегат».
Вот пять способов исправить ваш код:
Вариант 1: локальная копия i
Скопируйте значение i
в локальную переменную внутри цикла, чтобы каждая итерация цикла захватывала новую переменную влямбда-выражение.Эта новая переменная не изменяется во время выполнения цикла.
for (int i = 0; i < illegals.Length; i++)
{
int copy = i;
query = query.Where(c => c != illegals[copy]);
}
Вариант 2: извлекать нелегалов [i] вне лямбда-выражения
Извлеките значение illegals[i]
в цикле (вне лямбда-выражения) и используйте это значение в лямбда-выражении.Опять же, изменяющееся значение i
не влияет на переменную.
for (int i = 0; i < illegals.Length; i++)
{
char illegal = illegals[i];
query = query.Where(c => c != illegal);
}
Опция 3: использовать цикл по каждому элементу
Эта опция корректно работает только сКомпиляторы C # 5 и более поздние, поскольку значение foreach
изменилось (в лучшую сторону) в C # 5.
foreach (char illegal in illegals)
{
query = query.Where(c => c != illegal);
}
Вариант 4: использовать Except
один раз
LINQ предоставляет метод для исключения набора: Except
.Это , а не , совсем не то же самое, что более ранние опции, поскольку вы получите только одну копию любого конкретного символа в вашем выводе.Таким образом, если e
не было в illegals
, вы получите результат "Tex resul" с указанными выше параметрами, но "Tex rsul" с использованием Except
.Тем не менее, стоит знать о:
// Replace the loop entirely with this
query = query.Except(illegals);
Вариант 5: Использовать Contains
один раз
Вы можете вызвать Where
один раз, с лямбда-выражением, которое вызываетContains
:
// Replace the loop entirely with this
query = query.Where(c => !illegals.Contains(c));