Lambda Scope Clarification

.net, c#, c#-4.0, lambda, scope

Solution

In `Example 1`, x is defined in the local scope of the lamdba expression and is not visible to the third line

In `Example 2`, now you've declared two variables named "x" at the same declaration scope (visibility is different)

With a lambda or anonymous method, it "captures" the scope at which it is running. If you have a local x in the same scope as the lambda definition, then it "captures" that x to pull into what the lambda can access--thus resulting in two definitions of "x". What you declare in the lambda doesn't get captured in the other direction so it isn't visible outside the lambda.

In `Example 3`, Now you're not using a variable that is local only the lambda outside the lambda, and not naming something the same at the same declaration scope.

Problem

Why does my parameter `x` behave so erratically? - Example 1 - Doesn't exist in the current context. - Example 2 - Cannot reuse `x` because it's defined in a 'child' scope. - Example 3 - Fine. This is the part where I am confused. Perhaps a different 'child' scope? Example 1: ``` List<int> list = new List<int> { 1, 2, 3, 4, 5 }; var result = list.Where(x => x < 3); Console.Write(result.ElementAt(x)); ``` creates this compile time error: The name 'x' does not exist in the current context which I expect. Example 2: ``` List<int> list = new List<int> { 1, 2, 3, 4, 5 }; var result = list.Where(x => x < 3); int x = 1; Console.Write(result.ElementAt(x)); ``` produces this compile-time error: A local variable named 'x' cannot be declared in this scope because it would give a different meaning to 'x', which is already used in a 'child' scope to denote something else I understand the scoping as answered in this question, Is there a reason for C#'s reuse of the variable in a foreach?. However, this is something I've never seen before. In addition, it makes the answers to this question, What is the scope of a lambda variable in C#?, incomplete or wrong. Example 3: ``` List<int> list = new List<int> { 1, 2, 3, 4, 5 }; List<string> stringList = new List<string> { "A", "B" }; var result = list.Where(x => x < 3); var result2 = stringList.Where(x => x != "A"); Console.Write(result2); ``` No errors produced. With the accepted answer, these blog posts from Eric Lippert helped me wrap my head around what was happening. If anyone is still confused: declaration space simple names

Original source

Related problems