2012-06-05 6 views
3

가능한 중복 :
Question about foreach and delegates익명 대표

내가 여기 무슨 일이 일어나고 있는지 현상을 알고 싶습니다 :

이 목록에 List<string> 변환 동일한 문자열을 반환하는 대리자가 잘못되었습니다.

입력 목록에서 foreach에 의해 반환되는 변수로 직접 작업 할 때 WrongConversion에서 발생합니다. 내가 먼저 로컬 변수를 할당하고 위임에 그를 사용 CorrectConversion에서

(목록에서 마지막 문자열마다 반환됩니다).

이 과제는 처음에는 불필요한 것처럼 보입니다.

입력 :

using System.Collections.Generic; 
class Program 
{ 
    delegate string StringReturner(); 

    static void Main(string[] args) 
    { 
    var list = new List<string> { "a", "b", "c" }; 
    Display(WrongConversion(list)); 
    Display(CorrectConversion(list)); 
    System.Console.ReadKey(); 
    } 
    static List<StringReturner> WrongConversion(List<string> list) 
    { 
    var result = new List<StringReturner>(); 
    foreach (var s in list) 
    { 
     result.Add(() => { return s; }); // <========= s is always "c" ? 
    } 
    return result; 
    } 
    static List<StringReturner> CorrectConversion(List<string> list) 
    { 
    var result = new List<StringReturner>(); 
    foreach (var s in list) 
    { 
     var localString = s;    // <========= What happens here? 
     result.Add(() => { return localString; }); 
    } 
    return result; 
    } 
    private static void Display(List<StringReturner> list) 
    { 
    foreach (var stringReturner in list) 
     System.Console.Write(stringReturner()); 
    System.Console.WriteLine(); 
    } 
} 

출력 :

ccc 
abc 
+0

백만 개의 질문이 중복되어 있습니다. 그것은 지역 변수를 닫는 것과 관련이 있습니다. – jason

답변

-2

이 C#에서 알려진 "버그"(VB.NET 너무 내 생각)입니다. 간단한 대답은 foreach 내부에서 범위를 지정하므로 각 itteration에 새 복사본이 사용되지만 다른 경우에는 s를 참조하기 만하면 결국 궁극적으로 C로 끝납니다. 가장 작은). 이런 종류의 이슈를 "해결"하기 위해 연습을했습니다.

foreach(var _s = ....) { 
    var s = _s; 
    /* code here that uses s */ 
} 

그런 대리인을 사용할 때마다.

+1

이것은 또한 StackOverflow 커뮤니티에 알려진 문제입니다. 따라서 중복으로 닫습니다. – jason