다음을 통해 공유


방법: foreach를 사용하여 컬렉션 클래스 액세스(C# 프로그래밍 가이드)

업데이트: 2011년 3월

다음 코드 예제에서는 foreach와 함께 사용할 수 있는 제네릭이 아닌 컬렉션 클래스의 작성 방법을 보여 줍니다. 이 예제에서는 문자열 토크나이저 클래스를 정의합니다.

참고

이 예제에서 보여 주는 방법은 제네릭 컬렉션 클래스를 사용할 수 없는 경우에만 사용하는 것이 좋습니다. IEnumerable<T>을 지원하는 형식이 안전한 제네릭 컬렉션 클래스를 구현하는 방법에 대한 예를 보려면 방법: 제네릭 목록에 대한 반복기 블록 만들기(C# 프로그래밍 가이드)를 참조하십시오.

이 예제에서 다음 코드 세그먼트는 Tokens 클래스를 사용하여 "This is a sample sentence." 문장에 대해 ' ' 및 '-'을 구분 기호로 사용하여 문장을 여러 토큰으로 분리합니다. 그런 다음 foreach 문을 사용하여 토큰을 표시합니다.

Tokens f = new Tokens("This is a sample sentence.", new char[] {' ','-'});

// Display the tokens.
foreach (string item in f)
{
    System.Console.WriteLine(item);
}

예제

내부적으로 Tokens 클래스에는 토큰을 저장하기 위한 배열이 사용됩니다. 배열은 IEnumeratorIEnumerable을 구현하기 때문에 이 코드 예제에서는 Tokens 클래스에서 메서드를 정의하는 대신 배열의 열거형 메서드(GetEnumerator, MoveNext, ResetCurrent)가 사용될 수 있었습니다. 메서드 정의는 메서드의 정의 방식 및 각 메서드의 역할을 명확히 나타내기 위해 예제에 포함되었습니다.

using System.Collections;

// Declare the Tokens class. The class implements the IEnumerable interface.
public class Tokens : IEnumerable
{
    private string[] elements;

    Tokens(string source, char[] delimiters)
    {
        // The constructor parses the string argument into tokens.
        elements = source.Split(delimiters);
    }

    // The IEnumerable interface requires implementation of method GetEnumerator.
    public IEnumerator GetEnumerator()
    {
        return new TokenEnumerator(this);
    }


    // Declare an inner class that implements the IEnumerator interface.
    private class TokenEnumerator : IEnumerator
    {
        private int position = -1;
        private Tokens t;

        public TokenEnumerator(Tokens t)
        {
            this.t = t;
        }

        // The IEnumerator interface requires a MoveNext method.
        public bool MoveNext()
        {
            if (position < t.elements.Length - 1)
            {
                position++;
                return true;
            }
            else
            {
                return false;
            }
        }

        // The IEnumerator interface requires a Reset method.
        public void Reset()
        {
            position = -1;
        }

        // The IEnumerator interface requires a Current method.
        public object Current
        {
            get
            {
                return t.elements[position];
            }
        }
    }


    // Test the Tokens class.
    static void Main()
    {
        // Create a Tokens instance.
        Tokens f = new Tokens("This is a sample sentence.", new char[] {' ','-'});

        // Display the tokens.
        foreach (string item in f)
        {
            System.Console.WriteLine(item);
        }
    }
}
/* Output:
    This
    is
    a
    sample
    sentence.  
*/

C#에서는 컬렉션 클래스가 foreach와의 호환을 위해 IEnumerableIEnumerator를 구현할 필요가 없습니다. 필수 요소인 GetEnumerator, MoveNext, ResetCurrent 멤버가 클래스에 있기만 하면 foreach를 사용할 수 있습니다. 인터페이스를 생략하면 Current의 반환 형식을 Object보다 구체적으로 정의할 수 있는 이점이 있습니다. 이러한 이점은 형식 안전성을 제공합니다.

예를 들어, 이전 예제에서 다음 줄을 변경합니다.

// Change the Tokens class so that it no longer implements IEnumerable.
public class Tokens
{
    // . . .

    // Change the return type for the GetEnumerator method.
    public TokenEnumerator GetEnumerator()
    {   }

    // Change TokenEnumerator so that it no longer implements IEnumerator.
    public class TokenEnumerator
    {
        // . . .

        // Change the return type of method Current to string.
        public string Current
        {   }
    }
 }

Current에서는 문자열을 반환하므로 다음 코드와 같이 호환되지 않는 형식이 foreach 문에 사용되면 컴파일러에서 이를 감지할 수 있습니다.

// Error: Cannot convert type string to int.
foreach (int item in f)  

IEnumerableIEnumerator를 생략하면 기타 공용 언어 런타임 언어의 foreach 문이나 그에 상응하는 문에서 컬렉션 클래스를 상호 운용할 수 없다는 단점이 있습니다.

참고 항목

참조

배열(C# 프로그래밍 가이드)

컬렉션 클래스(C# 프로그래밍 가이드)

System.Collections.Generic

개념

C# 프로그래밍 가이드

기타 리소스

C# 참조

변경 기록

날짜

변경 내용

이유

2011년 3월

명확한 설명을 제공하도록 수정되었습니다.

향상된 기능 관련 정보