Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo illustra come usare IEnumerable e le IEnumerator interfacce per creare una classe che è possibile usare in un'istruzione foreach .
Versione originale del prodotto: Visual Studio
Numero KB originale: 322022
Interfaccia IEnumerator
IEnumerable e IEnumerator vengono spesso usati insieme. Anche se queste interfacce sono simili (e hanno nomi simili), hanno scopi diversi.
L'interfaccia IEnumerator fornisce funzionalità iterative per una raccolta interna a una classe . IEnumerator richiede l'implementazione di tre metodi:
Metodo
MoveNext, che incrementa l'indice della raccolta di 1 e restituisce un valore bool che indica se è stata raggiunta la fine della raccolta.Metodo
Resetche reimposta l'indice della raccolta sul valore iniziale di -1. In questo modo l'enumeratore viene invalidato.Metodo
Current, che restituisce l'oggetto corrente inposition.public bool MoveNext() { position++; return (position < carlist.Length); } public void Reset() { position = -1; } public object Current { get { return carlist[position];} }
Interfaccia IEnumerable
L'interfaccia IEnumerable fornisce supporto per l'iterazione foreach . IEnumerable richiede l'implementazione del GetEnumerator metodo .
public IEnumerator GetEnumerator()
{
return (IEnumerator)this;
}
Quando usare l'interfaccia
Inizialmente, si potrebbe riscontrare confusione nell'uso di queste interfacce. L'interfaccia IEnumerator fornisce l'iterazione su un oggetto di tipo raccolta in una classe . L'interfaccia consente l'enumerazione IEnumerable usando un foreach ciclo . Tuttavia, il GetEnumerator metodo dell'interfaccia restituisce un'interfaccia IEnumerable IEnumerator . Per implementare IEnumerable, è quindi necessario implementare IEnumeratoranche . Se non si implementa IEnumerator, non è possibile eseguire il cast del valore restituito dal GetEnumerator metodo di IEnumerable all'interfaccia IEnumerator .
In sintesi, l'uso di IEnumerable richiede che la classe implementi IEnumerator. Se si vuole fornire supporto per foreach, implementare entrambe le interfacce.
Esempio dettagliato
Nell'esempio seguente viene illustrato come usare queste interfacce. In questo esempio le IEnumerator interfacce e IEnumerable vengono usate in una classe denominata cars. La cars classe ha una matrice interna di car oggetti . Le applicazioni client possono enumerare tramite questa matrice interna usando un foreach costrutto a causa dell'implementazione di queste due interfacce.
Seguire questa procedura per creare un nuovo progetto applicazione console in Visual C#:
- Avviare Microsoft Visual Studio .NET o Visual Studio.
- Scegliere Nuovo dal menu Filee quindi fare clic su Progetto.
- Fare clic su Progetti Visual C# in Tipi di progetto e quindi su Applicazione console in Modelli.
- Nella casella Nome digitare ConsoleEnum.
Rinominare Class1.cs in host.cs e quindi sostituire il codice in host.cs con il codice seguente:
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(); } } }Scegliere Aggiungi classe dal menu Progetto, quindi digitare car nella casella Nome.
Sostituire il codice in car.cs con il codice seguente:
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 namespaceScegliere Aggiungi classe dal menu Progetto per aggiungere un'altra classe al progetto e quindi digitare automobili nella casella Nome.
Sostituire il codice in cars.cs con il codice seguente:
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];} } } }Eseguire il progetto.
L'output seguente viene visualizzato nella finestra Console :
Ford 1992
Fiat 1988
Buick 1932
Ford 1932
Dodge 1999
Honda 1977
Procedure consigliate
L'esempio in questo articolo viene mantenuto il più semplice possibile per spiegare meglio l'uso di queste interfacce. Per rendere il codice più affidabile e assicurarsi che il codice usi le linee guida per le procedure consigliate correnti, modificare il codice come indicato di seguito:
- Implementare
IEnumeratorin una classe annidata in modo da poter creare più enumeratori. - Fornire la gestione delle eccezioni per il
Currentmetodo diIEnumerator. Se il contenuto della raccolta cambia, viene chiamato ilresetmetodo . Di conseguenza, l'enumeratore corrente viene invalidato e si riceve un'eccezioneIndexOutOfRangeException. Altre circostanze potrebbero anche causare questa eccezione. Implementare quindi unTry...Catchblocco per intercettare questa eccezione e generare un'eccezioneInvalidOperationException.
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);
}
}
}