연습: Visual Basic에서 IEnumerable(Of T) 구현
IEnumerable<T> 인터페이스는 한 번에 하나의 항목 값 시퀀스를 반환할 수 있는 클래스에 의해 구현됩니다. 데이터를 한 번에 하나의 항목으로 반환할 때의 이점은 전체 데이터 집합을 메모리에 로드하여 작업할 필요가 없다는 것입니다. 데이터에서 단일 항목을 로드하려면 충분한 메모리만 사용해야 합니다. IEnumerable(T)
인터페이스를 구현하는 클래스는 For Each
루프 또는 LINQ 쿼리와 함께 사용할 수 있습니다.
예를 들어 큰 텍스트 파일을 읽고 특정 검색 조건과 일치하는 파일에서 각 줄을 반환해야 하는 애플리케이션을 생각해 보세요. 애플리케이션은 LINQ 쿼리를 사용하여 지정된 조건과 일치하는 파일의 줄을 반환합니다. LINQ 쿼리를 사용하여 파일 내용을 쿼리하기 위해 애플리케이션은 파일의 내용을 배열 또는 컬렉션에 로드할 수 있습니다. 그러나 전체 파일을 배열 또는 컬렉션에 로드하면 필요한 것보다 훨씬 더 많은 메모리가 소비됩니다. LINQ 쿼리는 열거 가능한 클래스를 사용하여 파일 내용을 쿼리하고 검색 조건과 일치하는 값만 반환할 수 있습니다. 일치하는 값 몇 가지만 반환하는 쿼리는 메모리를 훨씬 적게 사용합니다.
IEnumerable<T> 인터페이스를 구현하여 원본 데이터를 열거 가능한 데이터로 노출하는 클래스를 만들 수 있습니다. IEnumerable(T)
인터페이스를 구현하는 클래스에는 원본 데이터를 반복하기 위해 IEnumerator<T> 인터페이스를 구현하는 다른 클래스가 필요합니다. 이러한 두 클래스를 사용하면 데이터의 항목을 특정 형식으로 순차적으로 반환할 수 있습니다.
IEnumerable(Of String)
인터페이스를 구현하는 클래스와 IEnumerator(Of String)
인터페이스를 구현하는 클래스를 만들어 한 번에 한 줄씩 텍스트 파일을 읽는 방법을 보여 줍니다.
참고 항목
일부 Visual Studio 사용자 인터페이스 요소의 경우 다음 지침에 설명된 것과 다른 이름 또는 위치가 시스템에 표시될 수 있습니다. 이러한 요소는 사용하는 Visual Studio 버전 및 설정에 따라 결정됩니다. 자세한 내용은 IDE 개인 설정을 참조하세요.
열거 가능한 클래스 만들기
열거 가능한 클래스 프로젝트 만들기
Visual Studio의 파일 메뉴에서 새로 만들기를 가리킨 다음, 프로젝트를 클릭합니다.
새 프로젝트 대화 상자의 프로젝트 형식 창에서 Windows가 선택되었는지 확인합니다. 템플릿 창에서 클래스 라이브러리를 선택합니다. 이름 상자에
StreamReaderEnumerable
를 입력한 다음 확인을 클릭합니다. 새 프로젝트가 표시됩니다.솔루션 탐색기에서 Class1.vb 파일을 마우스 오른쪽 단추로 클릭하고 이름 바꾸기를 클릭합니다. 파일 이름을
StreamReaderEnumerable.vb
로 바꾸고 ENTER 키를 누릅니다. 파일 이름을 바꾸면 클래스 이름도StreamReaderEnumerable
로 바뀝니다. 이 클래스는IEnumerable(Of String)
인터페이스를 구현합니다.StreamReaderEnumerable 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가를 가리킨 다음, 새 항목을 클릭합니다. 클래스 템플릿을 선택합니다. 이름 상자에
StreamReaderEnumerator.vb
를 입력하고 확인을 클릭합니다.
이 프로젝트의 첫 번째 클래스는 열거 가능한 클래스이며 IEnumerable(Of String)
인터페이스를 구현합니다. 이 제네릭 인터페이스는 IEnumerable 인터페이스를 구현하고 이 클래스의 소비자가 String
로 입력된 값에 액세스할 수 있도록 보장합니다.
IEnumerable을 구현하는 코드 추가
StreamReaderEnumerable.vb 파일을 엽니다.
Public Class StreamReaderEnumerable
다음 줄에서 다음을 입력하고 Enter 키를 누릅니다.Implements IEnumerable(Of String)
Visual Basic은
IEnumerable(Of String)
인터페이스에 필요한 멤버로 클래스를 자동으로 채웁니다.이 열거 가능한 클래스는 한 번에 한 줄씩 텍스트 파일에서 줄을 읽습니다. 다음 코드를 클래스에 추가하여 파일 경로를 입력 매개 변수로 사용하는 퍼블릭 생성자를 노출합니다.
Private _filePath As String Public Sub New(ByVal filePath As String) _filePath = filePath End Sub
IEnumerable(Of String)
인터페이스의 GetEnumerator 메서드 구현은StreamReaderEnumerator
클래스의 새 인스턴스를 반환합니다.IEnumerable(Of String)
인터페이스의 멤버만 노출해야 하므로IEnumerable
인터페이스의GetEnumerator
메서드의 구현을Private
으로 만들 수 있습니다.GetEnumerator
메서드에 대해 Visual Basic에서 생성한 코드를 다음 코드로 바꿉니다.Public Function GetEnumerator() As IEnumerator(Of String) _ Implements IEnumerable(Of String).GetEnumerator Return New StreamReaderEnumerator(_filePath) End Function Private Function GetEnumerator1() As IEnumerator _ Implements IEnumerable.GetEnumerator Return Me.GetEnumerator() End Function
IEnumerator를 구현하는 코드 추가
StreamReaderEnumerator.vb 파일을 엽니다.
Public Class StreamReaderEnumerator
다음 줄에서 다음을 입력하고 Enter 키를 누릅니다.Implements IEnumerator(Of String)
Visual Basic은
IEnumerator(Of String)
인터페이스에 필요한 멤버로 클래스를 자동으로 채웁니다.열거자 클래스는 텍스트 파일을 열고 파일 I/O를 수행하여 파일에서 줄을 읽습니다. 다음 코드를 클래스에 추가하여 파일 경로를 입력 매개 변수로 사용하는 퍼블릭 생성자를 노출하고 읽기 위해 텍스트 파일을 엽니다.
Private _sr As IO.StreamReader Public Sub New(ByVal filePath As String) _sr = New IO.StreamReader(filePath) End Sub
IEnumerator(Of String)
와IEnumerator
두 인터페이스에 대한Current
속성은 텍스트 파일의 현재 항목을String
로 반환합니다.IEnumerator(Of String)
인터페이스의 멤버만 노출해야 하므로IEnumerator
인터페이스의Current
속성을 구현을Private
으로 만들 수 있습니다.Current
속성에 대해 Visual Basic에서 생성한 코드를 다음 코드로 바꿉니다.Private _current As String Public ReadOnly Property Current() As String _ Implements IEnumerator(Of String).Current Get If _sr Is Nothing OrElse _current Is Nothing Then Throw New InvalidOperationException() End If Return _current End Get End Property Private ReadOnly Property Current1() As Object _ Implements IEnumerator.Current Get Return Me.Current End Get End Property
IEnumerator
인터페이스의MoveNext
메서드는 텍스트 파일의 다음 항목으로 이동하여Current
속성에서 반환되는 값을 업데이트합니다. 읽을 항목이 더 이상 없으면MoveNext
메서드가False
로 반환되고, 그러지 않으면MoveNext
메서드가True
로 반환됩니다.MoveNext
메서드에 다음 코드를 추가합니다.Public Function MoveNext() As Boolean _ Implements System.Collections.IEnumerator.MoveNext _current = _sr.ReadLine() If _current Is Nothing Then Return False Return True End Function
IEnumerator
인터페이스의Reset
메서드는 반복기가 텍스트 파일의 시작을 가리키도록 지시하고 현재 항목 값을 지웁니다.Reset
메서드에 다음 코드를 추가합니다.Public Sub Reset() _ Implements System.Collections.IEnumerator.Reset _sr.DiscardBufferedData() _sr.BaseStream.Seek(0, IO.SeekOrigin.Begin) _current = Nothing End Sub
IEnumerator
인터페이스의Dispose
메서드는 반복기가 제거되기 전에 관리되지 않는 모든 리소스가 해제되도록 보장합니다.StreamReader
개체에서 사용하는 파일 핸들은 관리되지 않는 리소스이며 반복기 인스턴스가 제거되기 전에 닫아야 합니다. Visual Basic에서Dispose
메서드에 대해 생성한 코드를 다음 코드로 바꿉니다.Private disposedValue As Boolean = False Protected Overridable Sub Dispose(ByVal disposing As Boolean) If Not Me.disposedValue Then If disposing Then ' Dispose of managed resources. End If _current = Nothing _sr.Close() _sr.Dispose() End If Me.disposedValue = True End Sub Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub Protected Overrides Sub Finalize() Dispose(False) End Sub
샘플 반복기 사용
For Next
루프 또는 LINQ 쿼리와 같이 IEnumerable
을 구현하는 개체가 필요한 컨트롤 구조체와 함께 코드에서 열거 가능한 클래스를 사용할 수 있습니다. 다음 예제에서는 LINQ 쿼리에 StreamReaderEnumerable
이 있는 것을 보여 줄 수 있습니다.
Dim adminRequests =
From line In New StreamReaderEnumerable("..\..\log.txt")
Where line.Contains("admin.aspx 401")
Dim results = adminRequests.ToList()
참고 항목
.NET