인터페이스는 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 Basic의 [파일 ] 메뉴에서 [새로 만들기]를 가리킨 다음 [프로젝트]를 클릭합니다.
새 프로젝트 대화 상자의 프로젝트 형식 창에서 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
GetEnumerator 인터페이스의
IEnumerable(Of String)
메서드 구현은StreamReaderEnumerator
클래스의 새 인스턴스를 반환합니다. 인터페이스의 멤버GetEnumerator
만 노출해야 하므로IEnumerable
인터페이스의Private
메서드 구현을IEnumerable(Of String)
로 수행할 수 있습니다. 메서드에 대해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
두 인터페이스인
Current
및IEnumerator(Of String)
의IEnumerator
속성은 텍스트 파일의 현재 항목을String
로 반환합니다. 인터페이스의Current
멤버만 노출해야 하기 때문에, 인터페이스의IEnumerator
속성 구현을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
MoveNext
인터페이스의IEnumerator
메서드는 텍스트 파일의 다음 항목으로 이동하고,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
인터페이스의
Reset
메서드는IEnumerator
반복기가 텍스트 파일의 시작을 가리키도록 지시하고 현재 항목 값을 지웁니다.Reset
메서드에 다음 코드를 추가합니다.Public Sub Reset() _ Implements System.Collections.IEnumerator.Reset _sr.DiscardBufferedData() _sr.BaseStream.Seek(0, IO.SeekOrigin.Begin) _current = Nothing End Sub
인터페이스의
Dispose
메서드는IEnumerator
반복기가 제거되기 전에 관리되지 않는 모든 리소스가 해제되도록 보장합니다. 개체에서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
샘플 반복기 사용
루프 또는 LINQ 쿼리와 같이 이 IEnumerable
을 구현하는 개체를 필요로 하는 컨트롤 구조와 함께 코드에서 열거 가능한 클래스를 For Next
사용할 수 있습니다. 다음 예제는 LINQ 쿼리에서 StreamReaderEnumerable
를 보여줍니다.
Dim adminRequests =
From line In New StreamReaderEnumerable("..\..\log.txt")
Where line.Contains("admin.aspx 401")
Dim results = adminRequests.ToList()
참고하십시오
- Visual Basic LINQ 소개
- 제어 흐름
- 루프 구조체
- For Each...Next 문
.NET