2010-06-22 4 views
21

논리적으로는 C#의 foreach 루프가 for 루프를 증가시키는 순서와 동일한 순서로 평가할 것이라고 생각할 수 있습니다. 실험적으로 그렇습니다. 그러나 MSDN 사이트에는 이와 같은 확인 메시지가 나타나지 않습니다.C#의 foreach 루프가 평가 순서를 보장합니까?

사이트에 정보를 포함시키지 않은 것 같은 명백한 대답일까요? 아니면 그것이 불규칙하게 행동 할 가능성이 있습니까?

답변

35

배열의 경우 (System.ArrayIEnumerable을 구현 함) 요소 순서대로 액세스합니다. 다른 유형 (IEnumerable 또는 GetEnumerator)의 경우 MoveNextCurrent 호를 번갈아 제공하여 제공된 순서대로 요소에 액세스합니다.

표준 상태 (ECMA-364 §15.8.4)

"의 foreach가 배열 요소를 통과 로되는 순서는 다음과 일차원 배열의 요소는 인덱스 길이 종료 인덱스 0 로 시작 인덱스가 증가하는 순서로 이송 - 다차원 배열의 1, 요소 는 우측 차원의 지수 먼저, 그 다음 왼쪽 사이즈 증가되도록 이송되고 , 등 왼쪽에. "

5

가치가있는 부분은 Reflector에서 많이 볼 수 있습니다. mscorlib에서 System.Array는 IEnumerable (위에서 설명한대로)을 구현하고 Array#GetEnumeratorArrayEnumerator을 반환합니다. 여기 ArrayEnumerator#MoveNext의 신체의 :

public bool MoveNext() 
{ 
    if (this._complete) 
    { 
     this.index = this.endIndex; 
     return false; 
    } 
    this.index++; 
    this.IncArray(); 
    return !this._complete; 
} 

분명히 하나의 예이지만, 대답은 : 그것은 구현까지 그리고 당신은, 또는 경우에 따라 소스를 검사하여 그들이 실험적으로 작업하는 대부분의 방법을 찾을 수 있습니다 .

11

foreachIEnumerable<T> 위에 구축되어 MSDN에 열거의 계약은 열거는 컬렉션의 첫 번째 요소 앞에 위치, 처음

을 말한다. ... 따라서 Current 값을 읽기 전에 열거자를 컬렉션의 첫 번째 요소로 이동하려면 MoveNext를 호출해야합니다.

Current는 MoveNext가 호출 될 때까지 동일한 개체를 반환합니다. MoveNext는 Current를 다음 요소로 설정합니다.

그래서 기본 모음은 분명 '첫 번째'요소를 가지고 있으며, 배열,리스트에 대한 경우 등, 당신이 foreach 행동 할 것을 기대할 수 각 요소는 명확한 '다음'요소가있는 경우 논리적이고 안정적이다. 첫 번째 시퀀스 나 다음 시퀀스가없는 집합과 같은 경우 불안정한 방식으로 동작 할 수 있습니다. IEnumerable의 상태를 변경하지 않고도 정의 된 순서가없는 컬렉션이라도 일치하지 않을 수 있습니다. 작업!

3

foreach의 경고는 해시 배열로, 해시 키로 인해 순서가 보장되지 않습니다.

관련 문제