IEnumerable을 지원하는 컬렉션을 반복하는 방법은 무엇입니까?


답변:


155

정규직은 다음을 수행합니다.

foreach (var item in collection)
{
    // do your stuff   
}

.ElementAt ()보다 빠릅니다. 불행히도 내 투표는 Alexa의 답변에 고정되어 있으므로 취소 할 수 없지만 이것이 최선의 답변입니다. +1
Leo Gurdian 2016

그렇다면 "IEnumerable의 가능한 다중 열거"를 어떻게 수정합니까?
SharpC

1
@SharpC : 가장 쉬운 방법은 결과를 List <T> 또는 배열로 가져온 다음이를 반복해야하는 다양한 위치로 전달하는 것입니다. 이렇게하면 결과의 (잠재적으로 비용이 많이 드는) 열거가 한 번만 발생하지만 결과를 메모리에 저장하는 비용이 발생합니다. 내 첫 번째 단계는 다중 열거가 실제로 문제인지 아닌지 알아내는 것입니다.
Fredrik Mörk 19

94

foreach루프 를 사용하는 이미 제안 된 방법과 함께, 구현하는 모든 객체가 메소드 를 통해 인터페이스를 IEnumerable제공 한다고도 언급했습니다 . 이 메서드는 일반적으로 필요하지 않지만 컬렉션을 수동으로 반복하는 데 사용할 수 있으며 컬렉션에 대한 자체 확장 메서드를 작성할 때 특히 유용합니다.IEnumeratorGetEnumerator

IEnumerable<T> mySequence;
using (var sequenceEnum = mySequence.GetEnumerator())
{
    while (sequenceEnum.MoveNext())
    {
        // Do something with sequenceEnum.Current.
    }
}

가장 좋은 예는 루프 에서는 불가능한 두 시퀀스를 동시에 반복하려는 경우 foreach입니다.


7
열거자를 폐기하는 것을 잊지 마십시오.
Eric Lippert

@Eric : 네, 놓치기 쉽기 때문에 추가하겠습니다.
Noldorin

1
IEnumerable이 아닌 IEnumerable <T> 개체에서만 작동한다고 생각합니다. IEnumerable로 캐스트해야하는 일반적인 경우가있어서 GetEnumerator 메서드를 사용할 수 없었습니다. 어쨌든 대부분의 경우에 좋습니다.
Fabio Milheiro

50

또는 아주 고전적인 구식 방법도

IEnumerable<string> collection = new List<string>() { "a", "b", "c" };

for(int i = 0; i < collection.Count(); i++) 
{
    string str1 = collection.ElementAt(i);
    // do your stuff   
}

아마도 당신은 또한이 방법을 원할 것입니다 :-)


9
왜 이렇게 많은 찬성표가 있습니까? 이것은 열거 가능한 것을 한 번이 아니라 2n 번 열거합니다.
Roman Reiner

1
@RomanReiner이 작동하기 때문에 일부 사람들은 성능에 대해 신경 쓰지 않습니다 :)
Khateeb321

@RomanReiner 이것은 좋은 예입니다. 한 컬렉션의 각 요소를 다른 컬렉션에 할당해야합니다. foreach를 사용하여이 작업을 수행 할 수
없다고

1
ElementAt의 구현을 살펴보면 컬렉션이 IList이면 []를 사용하여 인덱스의 요소를 반환한다는 것을 알 수 있습니다. 그러나 []와 동일한 성능을 제공합니다. 그렇지 않은 경우 Enumerator를 얻고 요소를 반환하기 전에 순차적으로 반복을 시작하므로 기본적으로 각 요소에 대해 새 열거자를 만들고 목록을 다시 탐색합니다.
Israel Garcia

1
그보다 더 나쁜 것은 IEnumerable이 Count () 또는 ElementAt ()을 지원하지 않는다는 것입니다. 나는 그가 IList를 생각하고 있다고 생각합니다. 이것은 실제로 질문에 전혀 답하지 않습니다.
krowe


0

컬렉션을 반환하기 전에 기다리는 것을 잊었을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.