Search code examples
c#linqcycle

LINQ ThenBy in circle


Why I have different results in gg?

  1. Version:

    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. Version:

    var kk = ff.OrderBy(el => el.path[0]);
    
     kk = kk
          .ThenBy(el => el.path.Length > 1
           ? el.path[1]
           : 0)
          .ThenBy(el => el.path.Length > 2
           ? el.path[2]
           : 0);
    
    var gg = kk.ToList();
    

I need result by Version 2, but i need in cycle


Solution

  • This is because any variable that is declared outside a lambda expression is not captured inside the lambda i.e. you don't create multiple versions of i in each of the lambdas.

    For example,

    List<Action> actions = new List<Action>();
    for (int i = 0 ; i < 10 ; i++) {
        actions.Add(() => Console.WriteLine(i));
    }
    actions.ForEach(x => x.Invoke());
    

    Prints 10 10 times, instead of 0 to 9 as you would expect. The same thing happens in your code. Your first code snippet is equivalent to this:

     kk = kk
      .ThenBy(el => el.path.Length > 1
       ? el.path[3]
       : 0)
      .ThenBy(el => el.path.Length > 2
       ? el.path[3]
       : 0);