foreach(var category in categories) {
a.AddRange(_db.Articles.Where(c => c.Categories.Contains(category)));
}
코드는 잘 실행, 아직 나는 람다 식에 사용 category
참조에서 "수정 폐쇄에 접근"에 대한 경고를 얻을.액세스
질문 :이 상황에서 어떤 경고가 표시됩니까?
foreach(var category in categories) {
a.AddRange(_db.Articles.Where(c => c.Categories.Contains(category)));
}
코드는 잘 실행, 아직 나는 람다 식에 사용 category
참조에서 "수정 폐쇄에 접근"에 대한 경고를 얻을.액세스
질문 :이 상황에서 어떤 경고가 표시됩니까?
경고는 Where
람다의 경우 변수 category
에 액세스하기 때문에 발생합니다. 모든 반복마다 값이 category
으로 변경되고 Where
이 지연되므로 현재 람다가 작성되었을 때의 값과 비교하여 category
의 현재 값이 표시됩니다.
이 경우에는 문제가 없습니다. Where
이 지연 평가 되더라도 AddRange
메서드는 프롬프트이므로 Where
의 평가가 완료됩니다. 따라서 Where
메서드는 예상 한 값인 category
을 보게됩니다.
경고를 제거하려면 단순히 반복 변수의 로컬 복사본을 선언하고이를 대신 캡처하십시오.
foreach(var category in categories) {
var localCategory = category;
a.AddRange(_db.Articles.Where(c => c.Categories.Contains(localCategory)));
}
foreach 루프에 대해 뭔가 잊어 버린 것 같습니다. 반복 변수'category'는 기술적으로 루프 오른쪽 밖에 있습니다. ? 이 의사 코드와 매우 흡사하다. int i; for (i = 10) {i ++; }'? 그렇다면 '범주'가 변경된 후'Where'가 평가 될 수 있다는 것을 이해합니다. 나는 정확하게 이해하고 있는가? –
@ one.beat.consumer 맞습니다. – JaredPar
"category"변수는 클로저에 있으며 LINQ 표현식 외부에서 수정할 수 있음을 알려줍니다.
몇 가지 설명은 질문 here을보십시오.
[이 관련 질문] (http://stackoverflow.com/questions/8898925/is-there-a-reason-for-cs-reuse-of-the-variable-in-a-foreach)을 참조하십시오. 도움이 될 수도 있습니다. –
음, "수정 된 폐쇄 (Access to Modified Closure)"(http://stackoverflow.com/questions/235455/access-to-modified-closure) "에 대해 SO에 12 건의 안타가 있습니다.이 중 하나가이 질문에 대답합니다. –
@ RaymondChen 거기에 있습니다,하지만 그들은 람다 컨텍스트를 해결하지 못했습니다 내가 물었습니다 유일한 이유입니다. 나는 closure의 개념을 이해하고,이 이상한 경우에 LINQ의 문맥에서 좀 더 구체적인 것을 의미 하는지를보고 싶었다. –