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.
Este artigo demonstra como usar as IEnumerable
interfaces e para IEnumerator
criar uma classe que você pode usar em uma foreach
instrução.
Versão original do produto: Visual Studio
Número original do KB: 322022
Interface do IEnumerator
IEnumerable
e IEnumerator
são freqüentemente usados juntos. Embora essas interfaces sejam semelhantes (e tenham nomes semelhantes), elas têm propósitos diferentes.
A IEnumerator
interface fornece funcionalidade iterativa para uma coleção interna a uma classe. IEnumerator
requer que você implemente três métodos:
O
MoveNext
método, que incrementa o índice de coleta em 1 e retorna um bool que indica se o final da coleção foi atingido.O
Reset
método, que redefine o índice de coleção para seu valor inicial de -1. Isso invalida o enumerador.O
Current
método, que retorna o objeto atual emposition
.public bool MoveNext() { position++; return (position < carlist.Length); } public void Reset() { position = -1; } public object Current { get { return carlist[position];} }
Interface IEnumerable
A IEnumerable
interface fornece suporte para a foreach
iteração. IEnumerable
requer que você implemente o GetEnumerator
método.
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
Quando usar qual interface
Inicialmente, você pode achar confuso usar essas interfaces. A IEnumerator
interface fornece iteração em um objeto do tipo coleção em uma classe. A IEnumerable
interface permite a enumeração usando um foreach
loop. No entanto, o GetEnumerator
IEnumerable
método da interface retorna uma IEnumerator
interface. Portanto, para implementar IEnumerable
o , você também deve implementar IEnumerator
o . Se você não implementar IEnumerator
o , não poderá converter o valor retornado do GetEnumerator
método de IEnumerable
para a IEnumerator
interface.
Em resumo, o uso de IEnumerable
requer que a classe implemente IEnumerator
. Se você quiser fornecer suporte para foreach
o , implemente as duas interfaces.
Exemplo passo a passo
O exemplo a seguir demonstra como usar essas interfaces. Neste exemplo, as IEnumerator
interfaces e IEnumerable
são usadas em uma classe chamada cars
. A cars
classe tem uma matriz interna de car
objetos. Os aplicativos cliente podem enumerar por meio dessa matriz interna usando um foreach
constructo devido à implementação dessas duas interfaces.
Siga estas etapas para criar um novo projeto de Aplicativo de Console no Visual C#:
- Inicie o Microsoft Visual Studio .NET ou Visual Studio.
- No menu Arquivo , aponte para Novoe clique em Projeto.
- Clique em Projetos do Visual C# em Tipos de Projeto e, em seguida, clique em Aplicativo de Console em Modelos.
- Na caixa Nome, digite ConsoleEnum.
Renomeie Class1.cs para host.cs e substitua o código em host.cs pelo seguinte código:
using System; namespace ConsoleEnum { class host { [STAThread] static void Main(string[] args) { cars C = new cars(); Console.WriteLine("\nInternal Collection (Unsorted - IEnumerable,Enumerator)\n"); foreach(car c in C) Console.WriteLine(c.Make + "\t\t" + c.Year); Console.ReadLine(); } } }
No menu Projeto, clique em Adicionar Classe e digite carro na caixa Nome.
Substitua o código em car.cs pelo seguinte código:
using System; using System.Collections; namespace ConsoleEnum { public class car { private int year; private string make; public car(string Make,int Year) { make=Make; year=Year; } public int Year { get {return year;} set {year=value;} } public string Make { get {return make;} set {make=value;} } }//end class }//end namespace
No menu Projeto, clique em Adicionar Classe para adicionar outra classe ao projeto e digite carros na caixa Nome.
Substitua o código em cars.cs pelo seguinte código:
using System; using System.Collections; namespace ConsoleEnum { public class cars : IEnumerator,IEnumerable { private car[] carlist; int position = -1; //Create internal array in constructor. public cars() { carlist= new car[6] { new car("Ford",1992), new car("Fiat",1988), new car("Buick",1932), new car("Ford",1932), new car("Dodge",1999), new car("Honda",1977) }; } //IEnumerator and IEnumerable require these methods. public IEnumerator GetEnumerator() { return (IEnumerator)this; } //IEnumerator public bool MoveNext() { position++; return (position < carlist.Length); } //IEnumerable public void Reset() { position = -1; } //IEnumerable public object Current { get { return carlist[position];} } } }
Execute o projeto .
A seguinte saída aparece na janela Console:
Ford 1992
Fiat 1988
Buick 1932
Ford 1932
Dodge 1999
Honda 1977
Práticas recomendadas
O exemplo neste artigo é mantido o mais simples possível para explicar melhor o uso dessas interfaces. Para tornar o código mais robusto e garantir que ele use as diretrizes atuais de práticas recomendadas, modifique o código da seguinte maneira:
- Implemente
IEnumerator
em uma classe aninhada para que você possa criar vários enumeradores. - Forneça tratamento de exceção para o
Current
método deIEnumerator
. Se o conteúdo da coleção for alterado, oreset
método será chamado. Como resultado, o enumerador atual é invalidado e você recebe umaIndexOutOfRangeException
exceção. Outras circunstâncias também podem causar essa exceção. Portanto, implemente umTry...Catch
bloco para capturar essa exceção e gerar umaInvalidOperationException
exceção.
using System;
using System.Collections;
namespace ConsoleEnum
{
public class cars : IEnumerable
{
private car[] carlist;
//Create internal array in constructor.
public cars()
{
carlist= new car[6]
{
new car("Ford",1992),
new car("Fiat",1988),
new car("Buick",1932),
new car("Ford",1932),
new car("Dodge",1999),
new car("Honda",1977)
};
}
//private enumerator class
private class MyEnumerator:IEnumerator
{
public car[] carlist;
int position = -1;
//constructor
public MyEnumerator(car[] list)
{
carlist=list;
}
private IEnumerator getEnumerator()
{
return (IEnumerator)this;
}
//IEnumerator
public bool MoveNext()
{
position++;
return (position < carlist.Length);
}
//IEnumerator
public void Reset()
{
position = -1;
}
//IEnumerator
public object Current
{
get
{
try
{
return carlist[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
} //end nested class
public IEnumerator GetEnumerator()
{
return new MyEnumerator(carlist);
}
}
}