Сортировка LINQ ThenBy в цикле

213
19 января 2018, 21:31

Почему получается разный результат в переменной gg?

  1. Вариант

    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();
    
  2. Вариант

    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();
    
Answer 1

Переменная 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
READ ALSO
Стиль кнопки в WPF

Стиль кнопки в WPF

Есть кнопкаНа ней сверху лежит StackPanel с картинкой и надписью

431
Проблемы с EntityFramework + SQLite

Проблемы с EntityFramework + SQLite

Пытаюсь подружить EF6 и SQLite базу данныхСоздал модель и контекст данных

263
Есть ли аналог prompt для Node.JS в консоли?

Есть ли аналог prompt для Node.JS в консоли?

Можно ли получать ответы от пользователя в консоли, когда запускаешь Node сервер? Например, как аналог prompt() из JS, когда тебе предлагают ввести...

525
Java script, откуда запущен скрипт

Java script, откуда запущен скрипт

Использую для своих проектов Nodejs + nw

343