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
Reset
che 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 IEnumerator
anche . 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 namespace
Scegliere 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
IEnumerator
in una classe annidata in modo da poter creare più enumeratori. - Fornire la gestione delle eccezioni per il
Current
metodo diIEnumerator
. Se il contenuto della raccolta cambia, viene chiamato ilreset
metodo . Di conseguenza, l'enumeratore corrente viene invalidato e si riceve un'eccezioneIndexOutOfRangeException
. Altre circostanze potrebbero anche causare questa eccezione. Implementare quindi unTry...Catch
blocco 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);
}
}
}