Почему получается разный результат в переменной gg?
Вариант
var kk = ff.OrderBy(el => el.path[0]);
for (var i = 1; i <= 2; i++)
{
kk = kk
.ThenBy(el => el.path.Length > i
? el.path[i]
: 0);
}
var gg = kk.ToList();
Вариант
var kk = ff.OrderBy(el => el.path[0]);
kk = kk
.ThenBy(el => el.path.Length > 1
? el.path[1]
: 0);
kk = kk
.ThenBy(el => el.path.Length > 2
? el.path[2]
: 0);
var gg = kk.ToList();
Переменная i захватывается лямбда-выражением:
kk = kk
.ThenBy(el => el.path.Length > i
? el.path[i]
: 0);
, которое компилятор воспринимает как: «возьми переменную i, запомни ее, и когда лямбда будет вызвана используй значение i на тот момент».
Выполняться выражение будет при обработке последовательности в строке:
var gg = kk.ToList();
, которая находится после цикла. В этот момент i содержит значение 3.
Исправить можно, создав отдельную переменную для лямбды, значение которой изменяться не будет:
for (var i = 1; i <= 2; i++)
{
var lambdaValue = i;
kk = kk
.ThenBy(el => el.path.Length > lambdaValue
? el.path[lambdaValue]
: 0);
Вообще хорошим тоном считается не использовать в LINQ изменяемые переменные.
Ошибку можно воспроизвести на более простом примере:
var i = 1;
//последовательность из одной единицы
var sequence = Enumerable.Range(0, 1).Select(val => i);
//что-то делаем с переменной
i = 1000;
//Ожидание: 1
Console.WriteLine(sequence.First());
//Реальность: 1000
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости