Porady: uzyskiwanie dostępu do klasy kolekcji za pomocą instrukcji foreach (Przewodnik programowania w języku C#)
Poniższy przykład kodu ilustruje sposób zapisu klasy nierodzajową kolekcji, która może być używany z foreach.Przykład definiuje klasę tokenizera ciąg znaków.
[!UWAGA]
W tym przykładzie reprezentuje zalecana praktyka tylko wtedy, gdy nie można użyć klasy rodzajowej kolekcji.Na przykład sposób implementacji klasy rodzajowej kolekcji typ palety, która obsługuje IEnumerable, zobacz Iteratory (C# i Visual Basic).
Na przykład następujący kod używa segmentu Tokens klasy, aby przerwać zdanie "To jest przykładowe zdanie." w tokenach przy użyciu ' ' i '-' jako separatory.Następnie kod wyświetla te tokeny za pomocą foreach instrukcji.
Tokens f = new Tokens("This is a sample sentence.", new char[] {' ','-'});
// Display the tokens.
foreach (string item in f)
{
System.Console.WriteLine(item);
}
Przykład
Wewnętrznie Tokens klasy używa tablicy do przechowywania tokenów.Ponieważ implementuje tablice IEnumerator i IEnumerable, przykładowy kod mógł użyć metody wyliczania tablicy (GetEnumerator, MoveNext, Reset, i Current) zamiast określające ich w Tokens klasy.Definicje metody są zawarte w przykładzie w celu wyjaśnienia, jak są definiowane i co jest każdy.
using System.Collections;
// Declare the Tokens class. The class implements the IEnumerable interface.
public class Tokens : IEnumerable
{
private string[] elements;
Tokens(string source, char[] delimiters)
{
// The constructor parses the string argument into tokens.
elements = source.Split(delimiters);
}
// The IEnumerable interface requires implementation of method GetEnumerator.
public IEnumerator GetEnumerator()
{
return new TokenEnumerator(this);
}
// Declare an inner class that implements the IEnumerator interface.
private class TokenEnumerator : IEnumerator
{
private int position = -1;
private Tokens t;
public TokenEnumerator(Tokens t)
{
this.t = t;
}
// The IEnumerator interface requires a MoveNext method.
public bool MoveNext()
{
if (position < t.elements.Length - 1)
{
position++;
return true;
}
else
{
return false;
}
}
// The IEnumerator interface requires a Reset method.
public void Reset()
{
position = -1;
}
// The IEnumerator interface requires a Current method.
public object Current
{
get
{
return t.elements[position];
}
}
}
// Test the Tokens class.
static void Main()
{
// Create a Tokens instance.
Tokens f = new Tokens("This is a sample sentence.", new char[] {' ','-'});
// Display the tokens.
foreach (string item in f)
{
System.Console.WriteLine(item);
}
}
}
/* Output:
This
is
a
sample
sentence.
*/
W języku C#, nie jest konieczne dla klasy kolekcji do wprowadzenia w życie IEnumerable i IEnumerator był zgodny z foreach.Jeśli klasa ma wymagane GetEnumerator, MoveNext, Reset, i Current członków, będzie on działał z foreach.Pominięcie interfejsów ma tę zaletę, umożliwiające zdefiniowanie typem zwracanym dla Current , jest ściślej określony niż Object.Zapewnia to bezpieczeństwo typu.
Na przykład można zmienić następujące wiersze w poprzednim przykładzie.
// Change the Tokens class so that it no longer implements IEnumerable.
public class Tokens
{
// . . .
// Change the return type for the GetEnumerator method.
public TokenEnumerator GetEnumerator()
{ }
// Change TokenEnumerator so that it no longer implements IEnumerator.
public class TokenEnumerator
{
// . . .
// Change the return type of method Current to string.
public string Current
{ }
}
}
Ponieważ Current zwraca wartość typu ciąg, kompilator może wykryć użyty niewłaściwy typ foreach instrukcji, jak pokazano w poniższym kodzie.
// Error: Cannot convert type string to int.
foreach (int item in f)
Wadą pominięcie IEnumerable i IEnumerator jest Klasa kolekcji jest już współdziała z foreach oświadczenia lub równoważne instrukcje innych typowych języków środowiska wykonawczego języka.
Zobacz też
Informacje
Tablice (Przewodnik programowania w języku C#)
Koncepcje
Przewodnik programowania w języku C#