IQueryable의 구현 작업을하고 있습니다. 하지만 심오한 부분에 뛰어 들기 전에 평가할 표현의 나무가 어떻게 생겼는지 완전히 이해하고 있는지 확인하고 싶습니다. 특히 LINQ 쿼리 구문이 컴파일 프로세스 중 메서드 구문으로 변환되는 방법에 대해 궁금합니다.LINQ는 명명 충돌을 어떻게 해결합니까?
저는 LINQPad를 사용하여 컴파일러에서 생성 된 메서드를 봅니다. 중첩 된 반복에서 상위 레벨 반복의 상태를 저장하기 위해 임시 변수 이름이 생성되었음을 확인했습니다. 물론
EventQueue
.SelectMany(
Event => Event.Acknowledgements,
(Event, Ack) =>
new
{
Event = Event,
Ack = Ack
}
)
.Where(temp0 => (temp0.Ack.User == User.Name))
.Select(temp0 => temp0.Event)
내 첫 번째 본능이 휴식과 무슨 일이 있었는지 볼을 시도하는 것입니다
from Event in EventQueue
from Ack in Event.Acknowledgements
where Ack.User == User.Name
select Event
이 동일합니다 예를 들면 다음과 같습니다. 그래서 다음 쿼리를 작성했습니다 :
from Event in EventQueue
from Ack in Event.Acknowledgements
let temp0 = Ack.User
where Ack.User == temp0
select Event
이것은 거의 "WHERE 1 = 1"이며 모든 이벤트를 반환합니다. 이 LINQPad 컴파일러에서 이러한 방법 체인을 당겨하지 않는 결론에 저를 주도하고있다
EventQueue
.SelectMany(
Event => Event.Acknowledgements,
(Event, Ack) =>
new
{
Event = Event,
Ack = Ack
}
)
.Select(
temp0 =>
new
{
temp0 = temp0,
temp0 = temp0.Ack.User // Anonymous object with identically-named properties
}
)
.Where(temp1 => (temp1.temp0.Ack.User == temp1.temp0))
.Select(temp1 => temp1.temp0.Event)
을하기 때문에, 그러나, 나는 주어진있어 메소드 체인 컴파일하지 않을 것 때문에이 작업을 어떻게 이해하지 않는다 쿼리는이 메서드 체인이 분명히 작동하지 않는 동안 작동합니다. LINQPad는 자체적으로 메서드 체인을 생성 할 가능성이 큽니다.
어떻게 C# 컴파일러 (이 경우 Roslyn)가 생성 된 코드와 명명 충돌을 처리합니까?