Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
A IEnumerable<T> interface é implementada por classes que podem retornar uma sequência de valores um item de cada vez. A vantagem de retornar dados um item de cada vez é que você não precisa carregar o conjunto completo de dados na memória para trabalhar com ele. Você só precisa usar memória suficiente para carregar um único item dos dados. Classes que implementam a IEnumerable(T) interface podem ser usadas com For Each loops ou consultas LINQ.
Por exemplo, considere um aplicativo que deve ler um arquivo de texto grande e retornar cada linha do arquivo que corresponda a critérios de pesquisa específicos. O aplicativo usa uma consulta LINQ para retornar linhas do arquivo que correspondem aos critérios especificados. Para consultar o conteúdo do arquivo usando uma consulta LINQ, o aplicativo pode carregar o conteúdo do arquivo em uma matriz ou coleção. No entanto, carregar todo o arquivo em uma matriz ou coleção consumiria muito mais memória do que o necessário. Em vez disso, a consulta LINQ poderia consultar o conteúdo do arquivo usando uma classe enumerável, retornando apenas valores que correspondem aos critérios de pesquisa. Consultas que retornam apenas alguns valores correspondentes consumiriam muito menos memória.
Você pode criar uma classe que implementa a interface para expor dados de origem IEnumerable<T> como dados enumeráveis. Sua classe que implementa a interface IEnumerable(T) exigirá outra classe que implemente a interface IEnumerator<T> para iterar por meio dos dados de origem. Essas duas classes permitem que você retorne itens de dados sequencialmente como um tipo específico.
Neste passo a passo, você criará uma classe que implementa a IEnumerable(Of String) interface e uma classe que implementa a IEnumerator(Of String) interface para ler um arquivo de texto uma linha de cada vez.
Observação
Seu computador pode mostrar nomes ou locais diferentes para alguns dos elementos de interface do usuário do Visual Studio nas instruções a seguir. A edição do Visual Studio que você tem e as configurações que você usa determinam esses elementos. Para obter mais informações, consulte Personalizando o IDE.
Criando a classe enumerável
Criar o projeto de classe enumerável
No Visual Basic, no menu Arquivo , aponte para Novo e clique em Projeto.
Na caixa de diálogo Novo Projeto , no painel Tipos de Projeto , verifique se o Windows está selecionado. Selecione Biblioteca de Classes no painel Modelos . Na caixa Nome , digite
StreamReaderEnumerablee clique em OK. O novo projeto é exibido.No Gerenciador de Soluções, clique com o botão direito do mouse no arquivo Class1.vb e clique em Renomear. Renomeie o arquivo
StreamReaderEnumerable.vbe pressione ENTER. Renomear o arquivo também renomeará a classe paraStreamReaderEnumerable. Essa classe implementará aIEnumerable(Of String)interface.Clique com o botão direito do mouse no projeto StreamReaderEnumerable, aponte para Adicionar e clique em Novo Item. Selecione o modelo de classe . Na caixa Nome , digite
StreamReaderEnumerator.vbe clique em OK.
A primeira classe neste projeto é a classe enumerável e implementará a IEnumerable(Of String) interface. Essa interface genérica implementa a interface IEnumerable e garante que consumidores dessa classe possam acessar valores tipados como String.
Adicionar o código para implementar o IEnumerable
Abra o arquivo StreamReaderEnumerable.vb.
Na linha depois
Public Class StreamReaderEnumerable, digite o seguinte e pressione ENTER.Implements IEnumerable(Of String)O Visual Basic preenche automaticamente a classe com os membros exigidos pela
IEnumerable(Of String)interface.Essa classe enumerável lerá linhas de um arquivo de texto uma linha de cada vez. Adicione o código a seguir à classe para expor um construtor público que usa um caminho de arquivo como um parâmetro de entrada.
Private _filePath As String Public Sub New(ByVal filePath As String) _filePath = filePath End SubSua implementação do GetEnumerator método da
IEnumerable(Of String)interface retornará uma nova instância daStreamReaderEnumeratorclasse. A implementação do métodoGetEnumeratorda interfaceIEnumerablepode ser feitaPrivate, pois é necessário expor apenas os membros da interfaceIEnumerable(Of String). Substitua o código que o Visual Basic gerou para osGetEnumeratormétodos pelo código a seguir.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
Adicionar o código para implementar o IEnumerator
Abra o arquivo StreamReaderEnumerator.vb.
Na linha depois
Public Class StreamReaderEnumerator, digite o seguinte e pressione ENTER.Implements IEnumerator(Of String)O Visual Basic preenche automaticamente a classe com os membros exigidos pela
IEnumerator(Of String)interface.A classe enumerador abre o arquivo de texto e executa a E/S do arquivo para ler as linhas do arquivo. Adicione o código a seguir à classe para expor um construtor público que usa um caminho de arquivo como um parâmetro de entrada e abrir o arquivo de texto para leitura.
Private _sr As IO.StreamReader Public Sub New(ByVal filePath As String) _sr = New IO.StreamReader(filePath) End SubAs propriedades
Currentdas interfacesIEnumerator(Of String)eIEnumeratorretornam o item atual do arquivo de texto como umString. A implementação da propriedadeCurrentda interfaceIEnumeratorpode ser feitaPrivate, porque você precisa expor apenas membros da interfaceIEnumerator(Of String). Substitua o código que o Visual Basic gerou para asCurrentpropriedades pelo código a seguir.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 PropertyO
MoveNextmétodo daIEnumeratorinterface navega até o próximo item no arquivo de texto e atualiza o valor retornado pelaCurrentpropriedade. Se não houver mais itens a serem lidos, oMoveNextmétodo retornaráFalse; caso contrário, oMoveNextmétodo retornaráTrue. Adicione o seguinte código aoMoveNextmétodo.Public Function MoveNext() As Boolean _ Implements System.Collections.IEnumerator.MoveNext _current = _sr.ReadLine() If _current Is Nothing Then Return False Return True End FunctionO método
Resetda interfaceIEnumeratororienta o iterador a apontar para o início do arquivo de texto e limpa o valor do item atual. Adicione o seguinte código aoResetmétodo.Public Sub Reset() _ Implements System.Collections.IEnumerator.Reset _sr.DiscardBufferedData() _sr.BaseStream.Seek(0, IO.SeekOrigin.Begin) _current = Nothing End SubO
Disposemétodo daIEnumeratorinterface garante que todos os recursos não gerenciados sejam liberados antes que o iterador seja destruído. O identificador de arquivo usado peloStreamReaderobjeto é um recurso não gerenciado e deve ser fechado antes que a instância do iterador seja destruída. Substitua o código que o Visual Basic gerou para oDisposemétodo pelo código a seguir.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
Usando o Iterador de Amostra
Você pode usar uma classe enumerável em seu código junto com estruturas de controle que exigem um objeto que implementa IEnumerable, como um For Next loop ou uma consulta LINQ. O exemplo a seguir mostra o StreamReaderEnumerable em uma consulta LINQ.
Dim adminRequests =
From line In New StreamReaderEnumerable("..\..\log.txt")
Where line.Contains("admin.aspx 401")
Dim results = adminRequests.ToList()