C #에서 람다 변수의 범위는 무엇입니까?
람다 변수의 범위에 대해 혼란 스럽습니다. 예를 들면 다음과 같습니다.
var query =
from customer in clist
from order in olist
.Where(o => o.CustomerID == customer.CustomerID && o.OrderDate == // line 1
olist.Where(o1 => o1.CustomerID == customer.CustomerID) // line 2
.Max(o1 => o1.OrderDate) // line 3
)
select new {
customer.CustomerID,
customer.Name,
customer.Address,
order.Product,
order.OrderDate
};
1 행에서 람다 변수 'o'를 선언했습니다. 이는 2 행에서 다시 선언 할 수 없음을 의미합니다 (또는 적어도 컴파일러가 시도하면 불평 함).하지만 'o1'이 이미 존재하더라도 3 행에 대해 불평하지 않습니다. ??
람다 변수의 범위는 무엇입니까?
대괄호는 단서를 제공합니다. 람다 변수는 선언 된 범위에서 캡처됩니다.
.Where(o => ... olist.Where(o1 => ...).Max(o1 => ...))
// |----------------------------------------------| scope of o
// |---------| scope of first o1
// |---------| scope of second o1
두 o1
변수에 대해 겹치는 부분이 없지만 둘 다 o
변수와 겹치거나 음영 처리 되므로 동일한 이름을 사용할 수 없습니다.
람다 매개 변수의 범위는 내부 람다 식 또는 범위를 포함하여 람다 식 본문의 전체 범위와 같습니다.
람다 식의 구문을 확장하고 친숙한 들여 쓰기를 추가하면 더 명확해질 수 있습니다 (아마도 yamen의 다이어그램 답변 만큼 명확하지는 않습니다 !).
.Where(o => {
return o.CustomerID == customer.CustomerID
&& o.OrderDate == olist.Where(
o1 => o1.CustomerID == customer.CustomerID
)
.Max(
o1 => o1.OrderDate
);
})
귀하의 통지 .Where().Max()
호출이 외부에 위치해 있습니다 .Where()
. o
외측 람다 (이 호출된다 내면 람다 내 외측 람다로 캡슐화 폐쇄 이미 내면 람다의 범위에 있는지 등), 및 파라미터로서 재사용 할 수 없다.
o1
두 개의 내부 람다가 서로 완전히 분리되어 있기 때문에 재사용 할 수 있으므로 둘 중 하나의 범위를 벗어나지 않습니다.
범위 중 하나에 다른 범위가 포함 된 경우 두 범위에서 동일한 변수 이름을 사용할 수 없습니다.
귀하의 질문에서는 o
외부 범위에 도입되었으므로 두 번째 Where()
또는에서 다시 사용할 수 없습니다. Max()
이러한 범위는 외부 범위에 포함되어 있기 때문입니다.
반면에 o1
하나는 다른 하나를 포함하지 않기 때문에 두 내부 범위 모두에서 사용할 수 있으므로 모호성이 없습니다.
lamda는 코드에서 익명 함수를 대체하기 때문에
동일한 범위
Where(o => o.CustomerID == customer.CustomerID && o.OrderDate == //line 1
olist.Where(o1 => o1.CustomerID == customer.CustomerID) //line 2
변수 "o"가 존재하는 기능의 범위입니다.
여기 세 번째 줄에서 이것은 변수의 새로운 스 크롭, 즉 새로운 함수 범위입니다.
다른 범위
.Max(o1 => o1.OrderDate) ) //line 3
따라서 line1 및 line2의 공명입니다. line1에 정의 된 varialbe "o"는 동일한 스 크롭으로 인해 line2에서 정의 할 수 없으며 line2에 정의 된 "o1"은 다른 기능 범위에 있으므로 line3에서 다시 정의 할 수 있습니다.
C #은 이와 같은 섀도 잉을 지원하지 않습니다.
이유 o1
는 다시 작동합니다 o1
. 이전 .
다른 변수와 동일합니다. 의 범위는 o
첫 번째의 전체 표현식 Where
이므로 첫 번째 안에있는 두 번째에서 다시 사용할 수 없습니다. 그러나 범위는 o1
두 번째 표현 일 뿐이 Where
므로 Max
두 번째 외부 에있는 표현에서 사용할 수 있습니다 Where
. 코드에서 :
// o scope lasts until the first bracket is closed
Where(o => o.CustomerID == customer.CustomerID && o.OrderDate ==
// o1 scope lasts until the second bracket is closed; the first is not yet closed here
olist.Where(o1 => o1.CustomerID == customer.CustomerID)
// The second bracket is closed, so o1 is already out of scope; o is still in scope
.Max(o1 => o1.OrderDate)
)
// The first bracket is closed, so o is finally out of scope
나는 당신의 코드에 따라 이렇게 상상해보십시오 ...
.Where(o => o.CustomerID == customer.CustomerID && o.OrderDate == // line 1
olist.Where(o1 => o1.CustomerID == customer.CustomerID) // line 2
.Max(o1 => o1.OrderDate) // line 3
)
설명의 조잡한 방법이지만 대괄호가 범위를 결정합니다. 두 번째 o1은 두 번째 안에 중첩되지 않습니다. 그렇지 않으면 동일한 문제가 발생합니다.
//outermost where
((BEGIN-o
//inner where
(BEGIN-o1 END-o1)
//max
(BEGIN-o1 END-o1)
END-o))
var external = 1;
//This is a scope
Action scope = new Action(() =>
{
//myVar is not accessible from outside
var myVar = 0 + external;
Console.WriteLine(myVar); //outputs 1
});
//Call the scope
scope();
//Console.WriteLine(myVar);//Will not compile
코드가 컴파일되면 Action에서 선언 된 void의 모든 논리가 ()=>{ ... }
이름이 엉망인 형식의 메서드로 이동됩니다.
The run time will call the newly created function when it is reaches that place on the stack.
You can pass values into a scope / lambda in various ways which is the same for getting them out.
Variables declared in a lambda are not accessible outside with their declared name.
It is also possible to utilize reflection to pull out the mangled name however I am not sure you require that. (Please let me know if I am wrong.)
참고URL : https://stackoverflow.com/questions/10494074/what-is-the-scope-of-a-lambda-variable-in-c
'program tip' 카테고리의 다른 글
Android 애플리케이션 내에서 SQLite 쿼리를 수행하는 방법은 무엇입니까? (0) | 2020.11.16 |
---|---|
KeyDown 이벤트에 응답하지 않는 양식 (0) | 2020.11.16 |
Ubuntu에 Intellij IDEA를 설치하는 방법은 무엇입니까? (0) | 2020.11.16 |
Swift에서 UITableView에 새 셀을 삽입하는 방법 (0) | 2020.11.16 |
자식은 Angular 2에서 부모 이벤트를 수신합니다. (0) | 2020.11.16 |