본문 바로가기
Delphi/클래스

커스텀 열거자(Custom Enumerator) 구현을 통한 For-In 루프 최적화

by MonoSoft 2026. 3. 4.
728x90
반응형

커스텀 열거자(Custom Enumerator) 구현을 통한 For-In 루프 최적화

델파이의 for..in 루프는 기본적으로 배열이나 TList 같은 
표준 컬렉션에서 작동합니다. 하지만 직접 만든 
복잡한 자료구조나 특정 조건에 맞는 데이터만 순회하고 싶을 때 
GetEnumerator 함수를 클래스에 구현하면, 
표준 컬렉션이 아니더라도 for..in 문법을 사용할 수 있습니다. 
이를 통해 내부 구현을 감추면서도 사용자에게는 
매우 직관적인 순회 인터페이스를 제공할 수 있습니다.

program CustomEnumeratorExample;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

type
  // 홀수만 순회하는 커스텀 열거자 클래스
  TOddEnumerator = class
  private
    FIndex: Integer;
    FData: TArray<Integer>;
  public
    constructor Create(AData: TArray<Integer>);
    function MoveNext: Boolean; // 다음 항목 존재 여부 확인
    property Current: Integer read FData[FIndex]; // 현재 값 반환
  end;

  // 열거자를 소유한 컨테이너 클래스
  TOddContainer = class
  private
    FItems: TArray<Integer>;
  public
    constructor Create(AItems: TArray<Integer>);
    // for..in 루프가 호출하는 필수 함수
    function GetEnumerator: TOddEnumerator;
  end;

{ TOddEnumerator }

constructor TOddEnumerator.Create(AData: TArray<Integer>);
begin
  FData := AData;
  FIndex := -1; // 첫 MoveNext 호출 시 0이 되도록 설정
end;

function TOddEnumerator.MoveNext: Boolean;
begin
  Result := False;
  while FIndex < High(FData) do
  begin
    Inc(FIndex);
    if (FData[FIndex] mod 2 <> 0) then // 홀수 조건 체크
    begin
      Result := True;
      Break;
    end;
  end;
end;

{ TOddContainer }

constructor TOddContainer.Create(AItems: TArray<Integer>);
begin
  FItems := AItems;
end;

function TOddContainer.GetEnumerator: TOddEnumerator;
begin
  Result := TOddEnumerator.Create(FItems);
end;

var
  Container: TOddContainer;
  Num: Integer;
begin
  // 1부터 10까지의 배열을 가진 컨테이너 생성
  Container := TOddContainer.Create([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
  try
    Writeln('--- 컨테이너 내의 홀수만 출력 ---');
    // 커스텀 열거자 덕분에 for..in 루프 사용 가능
    for Num in Container do
    begin
      Write(Num, ' ');
    end;
    Writeln;
  finally
    Container.Free;
  end;
  
  Readln;
end.

실행 결과
--- 컨테이너 내의 홀수만 출력 ---
1 3 5 7 9

GetEnumerator: 클래스 내에 이 이름의 함수가 있고, 
그 반환 객체가 MoveNext와 Current 멤버를 가지고 있다면 
델파이 컴파일러는 이를 열거 가능한 객체로 인식합니다.

MoveNext: 다음 데이터로 이동하고 성공 여부를 반환합니다. 
이 안에서 필터링 로직(예: 홀수 판별)을 구현할 수 있습니다.

Current: 현재 인덱스의 실제 값을 반환하는 읽기 전용 속성입니다.

장점: 복잡한 필터링 로직을 비즈니스 코드에서 분리하여 
캡슐화할 수 있으며, 코드의 가독성이 획기적으로 향상됩니다.

커스텀 열거자를 클래스로 만들면 힙 메모리 할당이 발생합니다. 
성능이 매우 중요한 루프라면 클래스 대신 
**레코드(Record)**를 사용하여 열거자를 구현하면 메모리 할당 
오버헤드 없이 동일한 기능을 수행할 수 있습니다. 
최신 VCL 라이브러리들도 성능 최적화를 위해 
레코드 기반 열거자를 많이 사용합니다.


#델파이 #delphi #GetEnumerator #MoveNext #Current 
#ForInLoop #IteratorPattern #ObjectPascal #커스텀컬렉션 #코드캡슐화

728x90
반응형

댓글