What is the scope of a lambda variable in C#?
The brackets give the clue - the lambda variable is captured in the scope of where it's declared:
.Where(o => ... olist.Where(o1 => ...).Max(o1 => ...))
// |----------------------------------------------| scope of o
// |---------| scope of first o1
// |---------| scope of second o1
Note that there's no overlap for the two o1
variables, but they both overlap (or shadow) the o
variable and hence can't use the same name.
The scope of a lambda parameter is equal to the entire scope of the body of the lambda expression, including any inner lambda expressions or scopes.
If we expand the syntax of your lambda expressions and add some friendly indentation it may become clearer (though probably nowhere as clear as yamen's diagrammatic answer!):
.Where(o => {
return o.CustomerID == customer.CustomerID
&& o.OrderDate == olist.Where(
o1 => o1.CustomerID == customer.CustomerID
)
.Max(
o1 => o1.OrderDate
);
})
Notice that your .Where().Max()
call is located within an outer .Where()
. The o
in the outer lambda is encapsulated by the outer lambda within your inner lambdas (this is called closure) such that it exists in the scope of your inner lambdas already, and cannot be reused as a parameter.
You can reuse o1
because your two inner lambdas are completely separate from each other, so it doesn't live beyond the scope of either one.
You cannot use the same variable name in two scopes if one of the scopes contains the other.
In your question, o
is introduced in the outer scope, so it cannot be used again in the second Where()
or in Max()
, because these scopes are contained in the outer one.
On the other hand, you can use o1
in both inner scopes because one does not contain the other, so there is no ambiguity there.