티스토리 뷰

C#의 Foreach 문은 다른 반복문인 While, Do, For를 이용한 루프보다 더 다양하게 사용할 수 있습니다. Foreach 구문은 어떠한 Collection에 대해서도 최상의 반복 코드를 만들어 낼 수 있습니다. 


MSDN에 따르면 Foreach 구문은 아래와 같이 정의가 됩니다.


foreach 문은 배열이나 System.Collections.IEnumerable 또는 System.Collections.Generic.IEnumerable<T> 인터페이스를 구현하는 개체 컬렉션에 있는 각 요소에 대해 포함 문 그룹을 반복하여 실합니다. foreach 문은 컬렉션을 반복 실행하여 원하는 정보를 얻는 용도로 사용할 수 있지만 예측할 수 없는 부작용을 방지하면서 소스 컬렉션의 항목을 추가하거나 제거하는 용도로는 사용할 수 없습니다. 


소스 컬렉션에서 항목을 추가하거나 제거해야 한다면 for 루프를 사용하십시오. 배열 또는 컬렉션의 각 요소에 대해 포함 문이 계속 실행됩니다. 컬렉션의 모든 요소에 대해 해당 문이 계속 실행된 후에 제어가 foreach 블록 다음 문으로 전달됩니다. foreach 블록의 모든 위치에서 break 키워드를 사용하여 루프를 벗어나거나 continue 키워드를 사용하여 루프의 다음 반복을 단계별로 실행할 수 있습니다. foreach 루프는 goto, return 또는 throw 문을 사용하여 종료할 수도 있습니다.

참조 : MSDN 홈페이지


위의 설명을 해석해 보자면, Foreach 구문은 Collection가 밀접한 연관을 가지고 있습니다. Collection에 대한 처리(추가 및 삭제는 불가)를 반복해서 해야 한다고 하면 Foreach 구문이 가장 좋은 성능을 냅니다. 


Collection이란?


글에서는 계속 Collection이라는 단어가 나옵니다. Collection은 자료구조의 일종으로, System.Collections 네임스페이스에는 목록, 큐, 비트 배열, 해시 테이블 및 Dictionary과 같은 다양한 개체의 컬렉션을 정의하고 있습니다. 


자료 구조에 대한 설명을 드리기엔 양이 너무 많기 때문에, Collection내의 어떠한 부분이 있는지만 확인을 하시고 따로 공부를 하셔야 하지 않을까 생각을 합니다. Collection에 대해서 알지 못한다면 한가지만 기억하도록 합시다. (그리고 나중에 공부하자구요..)


Collection은 동일한 데이터 타입을 가진 

여러 데이터를 효율적으로 처리하기 위해서 만들어놓은 자료구조입니다.


Collection 네임스페이스가 제공하는 클래스는 아래와 같습니다. 



Foreach에 대해서

Foreach의 장점을 보기 위해서 아래의 코드를 살펴보도록 하겠습니다. 


int[] foo = new int[100];


// Loop 1

foreach (int i in foo)

Console.WriteLine(i.ToString());


// Loop 2

foreach (int index = 0 ; index < foo.Length ; index++)

Console.WriteLine(index.ToString());


// Loop 3

int len = foo.Length;

foreach (int index = 0 ; index < len ; index++)

Console.WriteLine(index.ToString());


.NET Framework 1.1 이상 버전에서 위의 코드를 실행하면 C# 컴파일러는 Loop 1을 가장 빨리 처리하게 됩니다. 대부분의 C/C++ 개발자는 Loop 3이 가장 효율적일 것이라 생각하겠지만, C#에서는 가장 좋지 않은 방식입니다.


그 이유는 C#은 Managed 기반에서 수행이 되기 때문에 Console 이 호출되기 이전에 index가 foo.Length를 넘는지 넘지 않는지를 JIT 컴파일러에서 확인을 합니다. 하지만 Loop 3의 경우는 미리 foo.Length를 뽑아서 처리하기 때문에 반복문 밖에서 foo.Length를 한번 더 호출하는 비효율적인 코드가 되기 때문입니다.


JIT C# 컴파일러는 Length 프로퍼티를 루프 바깥쪽으로 이동시킨 코드를 좋아하지 않습니다. 


그럼 Foreach 구문의 장점에 대해서 설명을 드리도록 하겠습니다. 

  • 이 구문은 배열의 최소 및 최대 범위를 어떻게 확인하는지를 알기 때문에 개발자는 이에 대해 신경을 쓰지 않아도 됩니다.
  • 이 구문은 항상 읽기 전용이므로 Collection에 대한 값을 변경할 수 없습니다. 
  • 코드 내부에서 올바른 형변환을 수행하게 됩니다. 적절치 않은 타입이라면 Exception을 발생시켜 코드가 안정성이 높아집니다.
  • 다차원 배열에서도 사용할 수 있습니다.
  • 자신이 만든 Collection이 IEnumerable Interface를 구현하였으면 Foreach를 사용할 수 있습니다.
  • 자신이 만든 Collection이 IDisposable Interface를 구현했으면 JIT는 Finally 구문을 자동적으로 최적화 합니다.

Foreach는 매우 융통성 있는 언어 요소입니다. 배열의 최소. 최대 범위를 자동으로 결정하여 올바르게 코드를 만들어 주며 다차원 배열에 대해서도 활용이 가능할 뿐 아니라, 참조되는 타입이 올바른 타입일때 처리할 수 있도록 해줍니다. 그리고 무엇보다 JIT 컴파일러에서 효율적인 코드를 만들어 냅니다.

이는 개발자에게 높은 유지보수성과 생산성을 제공하게 될것입니다.

이 글이 도움이 되셨나요? 그렇다면 아래의 그림을 클릭해주세요.



댓글