[c#] 각 루프의 C #은 List <T>에서 어떤 순서로 반복됩니까?

C #의 foreach 루프가 System.Collections.Generic.List<T>개체 를 반복하는 순서에 대해 궁금 합니다.

같은 주제에 대한 또 다른 질문을 찾았 지만 만족할만한 답변이 없다고 생각합니다.

누군가는 순서가 정의되지 않았다고 말합니다. 그러나 다른 사람이 말했듯이 배열을 순회하는 순서는 고정되어 있습니다 (0에서 길이 -1까지). 8.8.4 foreach 문

또한 주문 (예 :)이있는 모든 표준 클래스에 대해서도 동일하게 적용됩니다 List<T>. 이를 뒷받침 할 문서를 찾을 수 없습니다. 따라서 지금은 그렇게 작동 할 수 있지만 다음 .NET 버전에서는 다를 수 있습니다 (가능성이 낮더라도).

나는 List(t).Enumerator운없이 문서를 보았습니다 .

또 다른 관련 질문 은 Java의 경우 문서에 구체적으로 언급되어 있습니다.

List.iterator()이 목록의 요소에 대한 반복자를 적절한 순서로 반환합니다. “

C # 문서에서 이와 같은 것을 찾고 있습니다.

미리 감사드립니다.

편집 : 모든 답변에 대해 감사합니다 (얼마나 빨리 답변을 받았는지 놀랍습니다). 모든 답변에서 내가 이해하는 List<T>것은 항상 색인 순서대로 반복 된다는 것 입니다. 하지만 .NET의 Java 문서List 와 유사하게이를 설명하는 문서의 명확한 평화를보고 싶습니다 .



답변

Microsoft 참조 소스 페이지List<T>열거 명시 적 반복은 0에서 길이-1로 이루어집니다 적혀있다 :

internal Enumerator(List<T> list) {
    this.list = list;
    index = 0;
    version = list._version;
    current = default(T);
}

public bool MoveNext() {

    List<T> localList = list;

    if (version == localList._version && ((uint)index < (uint)localList._size))
    {
        current = localList._items[index];
        index++;
        return true;
    }
    return MoveNextRare();
}

누군가에게 여전히 관련이 있기를 바랍니다.


답변

기본적으로는 최대의 IEnumerator구현 -하지만를 위해 List<T>항상, 즉 인덱서와 같은 순서로리스트의 자연 순서로 이동합니다 : list[0], list[1],list[2]

나는 그것이 명시 적으로 문서화되었다고 믿지 않는다. 적어도 나는 그러한 문서를 찾지 못했다. 그러나 나는 그것을 보장 된 것으로 취급 할 수 있다고 생각한다. 그 순서를 변경하면 모든 종류의 코드가 무의미하게 손상됩니다. 사실, 나는 IList<T>이것에 불복종하는 어떤 구현을 보면 놀랄 것 입니다. 분명히 그것을 구체적으로 문서화하는 것을 보는 것이 좋을 것입니다 …


답변

링크에서 허용되는 답변은 C # 언어 사양 버전 3.0, 페이지 240에 다음 과 같이 나와 있습니다 .

foreach가 배열의 요소를 순회하는 순서는 다음과 같습니다. 1 차원 배열의 경우 색인 0에서 시작하여 색인 길이 – 1로 끝나는 증가하는 색인 ​​순서로 요소가 순회됩니다. 다차원 배열의 경우 요소가 순회됩니다. 가장 오른쪽 차원의 인덱스가 먼저 증가하고 다음 왼쪽 차원이 증가하는 방식으로 왼쪽으로 증가합니다. 다음 예제는 요소 순서로 2 차원 배열의 각 값을 인쇄합니다.

using System;
class Test
{
  static void Main() {
      double[,] values = {
          {1.2, 2.3, 3.4, 4.5},
          {5.6, 6.7, 7.8, 8.9}
      };
      foreach (double elementValue in values)
          Console.Write("{0} ", elementValue);
      Console.WriteLine();
  }
}

생성 된 출력은 다음과 같습니다. 1.2 2.3 3.4 4.5 5.6 6.7 7.8 8.9 예제에서

int[] numbers = { 1, 3, 5, 7, 9 };
foreach (var n in numbers) Console.WriteLine(n);
the type of n is inferred to be int, the element type of numbers.


답변

순서는 foreach 루프를 사용하여 데이터 컬렉션을 순회하는 데 사용되는 반복기에 의해 정의됩니다.

인덱싱 가능한 표준 컬렉션 (예 : 목록)을 사용하는 경우 인덱스 0부터 시작하여 위로 이동하는 컬렉션을 탐색합니다.

순서를 제어해야하는 경우 고유 한 IEnumerable구현하여 컬렉션 반복이 처리되는 방식을 제어 하거나 foreach 루프를 실행하기 전에 원하는 방식으로 목록을 정렬 할 수 있습니다.

이것은 일반 목록에서 열거자가 작동 하는 방식을 설명합니다 . 처음에는 현재 요소가 정의되지 않았으며 MoveNext를 사용하여 다음 항목으로 이동합니다.

MoveNext 를 읽으면 컬렉션의 첫 번째 요소에서 시작하여 컬렉션의 끝에 도달 할 때까지 다음 요소로 이동 함을 나타냅니다.


답변

목록은 백업 저장소에있는 순서대로 항목을 반환하는 것처럼 보이므로 이러한 방식으로 목록에 추가되면 해당 방식으로 반환됩니다.

프로그램이 순서에 의존하는 경우 목록을 탐색하기 전에 정렬 할 수 있습니다.

선형 검색에는 다소 어리석은 일이지만 특정 방식으로 주문이 필요한 경우 해당 순서로 항목을 만드는 것이 가장 좋습니다.


답변

내가하려는 일에 대해 작동하지 않았지만 나를 위해 목록을 재정렬 했음에도 불구하고 빠른 코드 해킹과 비슷한 작업을 수행해야했습니다.

LINQ를 사용하여 순서 변경

         DataGridViewColumn[] gridColumns = new DataGridViewColumn[dataGridView1.Columns.Count];
         dataGridView1.Columns.CopyTo(gridColumns, 0); //This created a list of columns

         gridColumns = (from n in gridColumns
                        orderby n.DisplayIndex descending
                        select n).ToArray(); //This then changed the order based on the displayindex


답변