2009-10-27 6 views
9

여기에 표시된대로 http://www.albahari.com/nutshell/predicatebuilder.aspx과 같이 PredicateBuilder를 사용하면 모든 것이 훌륭하게 작동합니다. 이제는 동적 LINQ를 SQL 식으로 생성 할 수 있지만 이해할 수없는 점은 왜 이런 루프에있을 때입니까?LINQ to SQL PredicateBuilder

난 그 임시 변수를 사용해야하는 이유
var inner = PredicateBuilder.False<MyType>(); 
foreach (var f in Filtermodel.InstrumentsFilterList.Where(s => s.isActive)) 
     { 
      int temp = f.InstrumentID; 
      inner = inner.Or(ud => ud.InstrumentId == temp); 
     } 

은?, 나는 "F"반복자 변수를 사용하려고하지만 참조에 의해 전달처럼 만 ... 각 반복에 대해

을 목록의 마지막 값을 얻을

답변

10

PredicateBuilder는 나중에 시점에서 실행될 표현식을 작성하기 때문에. 컴파일러가 델리게이트의 클로저를 생성 할 때 현재 범위에서 생성 된 모든 값을 찾아서 클로저로 전달합니다. InstrumentID는 값 유형 (int)이므로 값을 초기화하고 복사하면 각 대리자/클로저가 해당 값을 전달합니다. 매번 값의 복사본을 만들지 않으면 표현식은 기본 값이 아닌 f.InstrumentID에 대한 리터럴 참조를 갖습니다. 나중에식이 실제로 실행될 때 f.InstrumentID가 평가되고 마지막으로 설정된 값 (마지막 반복)이 나오게됩니다.

+0

이것은 꽤 흥미로운 것 같습니다.이 주제에 대한 문서를 어디에서 얻을 수 있습니까? – JOBG

2

조건을 평가하지 않고 표현을 작성하기 때문에. 표현식은 foreach에 정의 된 변수에 바인드됩니다.이 변수는 전체 루프를 실행하는 동안 참조를 유지합니다. 임시 변수로 각 변수를 재정의하면 각 표현식이 다른 변수를 사용하게되어 모든 반복에서 단일 참조를 참조하고 마지막 반복 만의 값을 가지지 않고 각 반복에서 값이있는 인스턴스를 참조하도록합니다.

+0

감사합니다. 이것은 약간 까다 롭습니다. 배열을 가지고 놀고있는 시간을 기억하고 값으로 값을 복사하려고합니다. 두통, 아마도. 간단히 말하면, 이것은 값의 게으른로드를 의미하며, 시간에 대한 값 변화와 theres는 "f"의 단지 한 순간입니다. – JOBG