Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Lambda variable scope exists outside LINQ Query?

Tags:

scope

c#

.net

linq

I read this question(What is the scope of a lambda variable in C#?)

But it is about Lambda variable scope inside LINQ Query.

Now to my question

Lets say I have a very simple LINQ query.

var Foo = FoobBar.Select(x => x);
var x = somefunction();

Compiler says : A local variable '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.

Why is that so? Shouldn't Lambda variable cease to exist when LINQ query ends?

EDIT: After reading answers i came to conclusion that its the outside x (returned from function) whose scope extends inside LINQ Query.

like image 440
Nikhil Agrawal Avatar asked May 23 '12 07:05

Nikhil Agrawal


3 Answers

It's not about LINQ it's about child scopes.

For example:

foreach (var bar in FooBar.Bars)
        {
            var x = FooBar.GetFoo();
        }
var x = new Foo();

produces exactly the same error message from compiler.

To fix that you just have to place variables in different (non-nesting) scopes. For example:

foreach (var bar in FooBar.Bars)
        {
            var x = FooBar.GetBar();
        }
{
    var x = new Foo();
}
like image 135
default locale Avatar answered Nov 02 '22 22:11

default locale


Lets look carefully,

var Foo = FoobBar.Select(x => x);

true the scope of x ends in the expression

var x = somefunction()

Now this is interesting, this is scoped for the entire method which holds the lamda expression too, so the compiler cannot distinguish since the scope of the latter overlaps the former. and very informative message too give a different meaning to 'x', which is already used in a 'child' scope (Select as in your case)

Similar scope question

maybe you can include braces around the other so that it's scope is defined

{
var x = somefunction()
}
like image 41
V4Vendetta Avatar answered Nov 02 '22 23:11

V4Vendetta


Think if C# would allow those two variables to exist on same scope level, this will not be possible:

static void test() {

    Action<int> x = (z) => {
        Console.WriteLine(z);               
    };


    int[] i = { 5,2,0,1,3,1,4 };

    var kyrie = i.Select (x => x);

}

How you would say to C# that you wanted to assign the Action delegate named x to kyrie variable; or the vice versa, how you would say to C# you wanted to use the integer projection itself? How C# would resolve that?

And C# scoping resolution is very consistent whether you declare it before the other variable or after the other variables, they are the same. e.g. http://www.anicehumble.com/2012/05/java-said-c-said-scope-consistency.html

To disambiguate those scenario, C# doesn't allow you to compile a program that have variable names that exists on same level

It's all about expressing your intent to the compiler in a non-ambiguous way. And C# did a good job on that regard

like image 25
Michael Buen Avatar answered Nov 02 '22 22:11

Michael Buen