0Pricing
C# Academy · 강의

사용자 지정 열거 가능 형식

반복자를 사용해 IEnumerable을 구현합니다.

사용자 지정 열거 가능 형식은(는) CoddyKit의 무료 C# Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C# Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

사용자 지정 열거 가능 형식 만들기

클래스에 IEnumerable<T>를 구현하면 foreach에서 사용할 수 있게 됩니다. 반복자 메서드와 결합하면 적은 코드로 사용자 지정 컬렉션과 범위를 만들 수 있습니다.

yield를 사용한 GetEnumerator 구현

IEnumerable<T>를 구현하는 가장 간단한 방법은 GetEnumerator를 yield return을 사용하는 반복자로 작성하는 것입니다. 컴파일러가 열거자를 대신 만들어 줍니다.

using System;
using System.Collections;
using System.Collections.Generic;

public class IntRange : IEnumerable<int>
{
    private readonly int _start, _count;
    public IntRange(int start, int count) { _start = start; _count = count; }

    public IEnumerator<int> GetEnumerator()
    {
        for (int i = 0; i < _count; i++)
            yield return _start + i;
    }
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

public class Program
{
    public static void Main()
    {
        foreach (var n in new IntRange(5, 4))
            Console.WriteLine(n);
    }
}

GetEnumerator 메서드가 두 개 필요한 이유

IEnumerable<T>는 제네릭이 아닌 IEnumerable을 상속하므로 두 가지를 모두 구현해야 합니다. 명시적 비제네릭 구현은 제네릭 버전에 작업을 위임할 뿐입니다.

using System;
using System.Collections;
using System.Collections.Generic;

public class Letters : IEnumerable<char>
{
    public IEnumerator<char> GetEnumerator()
    {
        yield return 'x';
        yield return 'y';
        yield return 'z';
    }
    // Required because IEnumerable<T> extends IEnumerable
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

public class Program
{
    public static void Main()
    {
        foreach (var c in new Letters())
            Console.WriteLine(c);
    }
}

사용자 지정 로직 캡슐화

사용자 지정 열거 가능 형식은 복잡한 생성 규칙을 깔끔한 형식 뒤에 숨길 수 있습니다. 여기서는 클래스가 선택한 길이만큼 Fibonacci 시퀀스를 생성합니다.

using System;
using System.Collections;
using System.Collections.Generic;

public class Fibonacci : IEnumerable<int>
{
    private readonly int _count;
    public Fibonacci(int count) { _count = count; }

    public IEnumerator<int> GetEnumerator()
    {
        int a = 0, b = 1;
        for (int i = 0; i < _count; i++)
        {
            yield return a;
            int next = a + b; a = b; b = next;
        }
    }
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

public class Program
{
    public static void Main()
    {
        foreach (var n in new Fibonacci(8))
            Console.WriteLine(n);
    }
}

내부 컬렉션 감싸기

사용자 지정 열거 가능 형식은 내부 저장소를 감싸고, 항목 추가 또는 필터링 방식을 제어하면서 열거 기능을 노출하는 경우가 많습니다.

using System;
using System.Collections;
using System.Collections.Generic;

public class EvenBag : IEnumerable<int>
{
    private readonly List<int> _items = new List<int>();
    public void Add(int n) { if (n % 2 == 0) _items.Add(n); }

    public IEnumerator<int> GetEnumerator() => _items.GetEnumerator();
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

public class Program
{
    public static void Main()
    {
        var bag = new EvenBag();
        bag.Add(1); bag.Add(2); bag.Add(3); bag.Add(4);
        foreach (var n in bag) Console.WriteLine(n);
    }
}

사용자 지정 열거 가능 형식은 LINQ와 함께 작동

IEnumerable<T>를 구현하는 모든 형식은 즉시 LINQ의 모든 기능을 사용할 수 있습니다. 사용자 지정 컬렉션을 무료로 필터링하고, 투영하고, 집계할 수 있습니다.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public class IntRange : IEnumerable<int>
{
    private readonly int _start, _count;
    public IntRange(int start, int count) { _start = start; _count = count; }
    public IEnumerator<int> GetEnumerator()
    {
        for (int i = 0; i < _count; i++) yield return _start + i;
    }
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

public class Program
{
    public static void Main()
    {
        var range = new IntRange(1, 10);
        Console.WriteLine(range.Where(n => n % 3 == 0).Sum());
    }
}

각 foreach는 새로운 열거자를 가져옴

반복할 때마다 GetEnumerator가 호출되므로 사용자 지정 열거 가능 형식을 여러 번 열거할 수 있으며, 순회할 때마다 새로 시작합니다.

using System;
using System.Collections;
using System.Collections.Generic;

public class IntRange : IEnumerable<int>
{
    private readonly int _count;
    public IntRange(int count) { _count = count; }
    public IEnumerator<int> GetEnumerator()
    {
        for (int i = 1; i <= _count; i++) yield return i;
    }
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

public class Program
{
    public static void Main()
    {
        var r = new IntRange(3);
        foreach (var n in r) Console.Write(n);
        Console.WriteLine();
        foreach (var n in r) Console.Write(n); // fresh again
        Console.WriteLine();
    }
}

제네릭 사용자 지정 열거 가능 형식

어떤 요소 형식이든 담을 수 있도록 열거 가능 형식을 제네릭으로 만드십시오. 여기서는 간단한 ring이 선택한 오프셋에서 시작해 항목을 순서대로 노출합니다.

using System;
using System.Collections;
using System.Collections.Generic;

public class Ring<T> : IEnumerable<T>
{
    private readonly T[] _items;
    private readonly int _start;
    public Ring(T[] items, int start) { _items = items; _start = start; }

    public IEnumerator<T> GetEnumerator()
    {
        for (int i = 0; i < _items.Length; i++)
            yield return _items[(_start + i) % _items.Length];
    }
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

public class Program
{
    public static void Main()
    {
        var ring = new Ring<string>(new[] { "a", "b", "c", "d" }, 2);
        foreach (var s in ring) Console.WriteLine(s);
    }
}

지연 사용자 지정 열거 가능 형식

GetEnumerator 자체가 반복자이므로 사용자 지정 열거 가능 형식은 기본적으로 지연 방식으로 작동합니다. 소비자가 요청할 때만 항목이 생성됩니다.

using System;
using System.Collections;
using System.Collections.Generic;

public class Squares : IEnumerable<int>
{
    private readonly int _count;
    public Squares(int count) { _count = count; }
    public IEnumerator<int> GetEnumerator()
    {
        for (int i = 1; i <= _count; i++)
        {
            Console.WriteLine("computing " + i);
            yield return i * i;
        }
    }
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

public class Program
{
    public static void Main()
    {
        foreach (var n in new Squares(3))
            Console.WriteLine("got " + n);
    }
}

사용자 지정 열거 가능 형식을 만들 시점

트리 순회, 페이지로 나뉜 데이터 source, 수학적 수열처럼 순회 순서나 생성 로직이 형식의 핵심 부분일 때 사용자 지정 열거 가능 형식을 사용하십시오. 그 외에는 일반 반복자 메서드로 충분합니다.

using System;
using System.Collections;
using System.Collections.Generic;

public class Countdown : IEnumerable<int>
{
    private readonly int _from;
    public Countdown(int from) { _from = from; }
    public IEnumerator<int> GetEnumerator()
    {
        for (int i = _from; i >= 0; i--) yield return i;
    }
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

public class Program
{
    public static void Main()
    {
        foreach (var n in new Countdown(5)) Console.WriteLine(n);
    }
}

직접 해 보기

기하 수열을 생성하는 사용자 지정 열거 가능 형식을 만든 다음 LINQ를 사용해 보십시오. 만든 형식이 전체 생태계에 바로 연결됩니다.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public class Geometric : IEnumerable<int>
{
    private readonly int _start, _ratio, _count;
    public Geometric(int start, int ratio, int count) { _start = start; _ratio = ratio; _count = count; }
    public IEnumerator<int> GetEnumerator()
    {
        int value = _start;
        for (int i = 0; i < _count; i++) { yield return value; value *= _ratio; }
    }
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

public class Program
{
    public static void Main()
    {
        var seq = new Geometric(1, 2, 6);
        Console.WriteLine(string.Join(", ", seq));
        Console.WriteLine("sum: " + seq.Sum());
    }
}

빠른 확인

IEnumerable<T> 계약을 떠올려 보십시오.

정리

사용자 지정 열거 가능 형식은 IEnumerable<T>를 구현하므로 foreach 및 LINQ와 함께 작동합니다.

  • GetEnumerator를 yield return을 사용하는 반복자로 구현하십시오.
  • 명시적 비제네릭 GetEnumerator도 제공하십시오.
  • 반복할 때마다 새로운 열거자를 가져옵니다.
  • 반복은 기본적으로 지연 방식으로 수행됩니다.

자주 묻는 질문

“사용자 지정 열거 가능 형식” 강의는 무료인가요?

네 — “사용자 지정 열거 가능 형식” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C# Academy 강의 전체를 잠금 해제할 수 있습니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“사용자 지정 열거 가능 형식”에서 뭘 배우나요?

반복자를 사용해 IEnumerable을 구현합니다. 브라우저에서 직접 실행하는 실습 코드로 C# Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

C# Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 C# Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“사용자 지정 열거 가능 형식” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 C# Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 C# Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. yield return을 사용하는 반복자 메서드
  2. yield break와 조기 종료
  3. 지연 평가 의미
  4. 사용자 지정 열거 가능 형식
← C# Academy(으)로 돌아가기