5

When I do this:

currentPage = metadataResponse.ApplicationType.Pages.Find(
   page => page.SortOrder == ++currentPage.SortOrder);

The value of currentPage is null.

But the same logic, when I assign the increment value to an integer variable, and then try to get the currentPage

int sortOrder = ++currentPage.SortOrder;
currentPage = metadataResponse.ApplicationType.Pages.Find(
    page => page.SortOrder == sortOrder);

currentPage gets populated.

Does anyone have a good answer as to why one works and the other doesn't?

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • 5
    They're not equivalent, simple as that. Apparently the lambda is being evaluated multiple times (I don't know what the `Find()` method is) and is changing the current page's sort order multiple times. – Jeff Mercado Feb 05 '16 at 23:54
  • 5
    Avoid lambda expressions with side effects in queries. – Michael Liu Feb 05 '16 at 23:58

1 Answers1

6

Note: I assume Find method is applied to a collection of values.

In the first code example, you are incrementing currentPage for each element in your collection (this is happening because lambda expressions introduce closures over variables captured from outer scope - see below code block for more info about that). In the second code example, currentPage is incremented only once. Take a look how the following program behaves:

class Program
{
    static void Main(string[] args)
    {
        Func1();
        Console.WriteLine("\n");
        Func2();

        Console.ReadKey();
    }

    private static void Func1()
    {
        int i = 0;
        var list = new List<int> { 1, 2, 3 };
        list.ForEach(x => Console.WriteLine(++i));
    }

    private static void Func2()
    {
        int i = 0;
        int j = ++i;
        var list = new List<int> { 1, 2, 3 };
        list.ForEach(x => Console.WriteLine(j));
    }
}

Here is some more info about closures in lambda expressions. Have fun! ;-)

Community
  • 1
  • 1
Kapol
  • 6,383
  • 3
  • 21
  • 46