Gewusst wie: Zugreifen auf Auflistungsklassen mit foreach (C#-Programmierhandbuch)

Das folgende Codebeispiel zeigt, wie Sie eine nicht generische Auflistungsklasse schreiben, die mit foreach verwendet werden kann. Das Beispiel definiert eine Zeichenfolgen-Tokenisierungsklasse.

Hinweis

Das Beispiel stellt nur die empfohlene Vorgehensweise dar, wenn Sie keine generische Auflistungsklasse verwenden können. Ein Beispiel wie eine typsichere generische Auflistungsklasse implementiert wird, die IEnumerable<T> unterstützt, finden Sie unter Iteratoren (C# und Visual Basic).

Im Beispiel verwendet das folgende Codesegment die Tokens-Klasse, um den Satz „Dies ist ein Beispielsatz“ in Token aufzuteilen, indem „ “ und „-“ als Trennzeichen verwendet werden. Der Code zeigt anschließend diese Tokens mithilfe einer foreach-Anweisung an.

Tokens f = new Tokens("This is a sample sentence.", new char[] {' ','-'});

// Display the tokens.
foreach (string item in f)
{
    System.Console.WriteLine(item);
}

Beispiel

Die Tokens-Klasse verwendet intern ein Array, um die Token zu speichern. Da Arrays IEnumerator und IEnumerable implementieren, hätte das Codebeispiel die Enumerationsmethoden des Arrays verwenden können (GetEnumerator, MoveNext, Reset und Current), anstatt sie in der Tokens-Klasse zu definieren. Die Methodendefinitionen sind im Beispiel enthalten, um zu verdeutlichen, wie sie definiert sind und was jede Definition tut.

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.  
*/

In C# muss eine Auflistungsklasse nicht IEnumerable und IEnumerator implementieren, um mit foreach kompatibel zu sein. Wenn die Klasse über die erforderlichen Elemente GetEnumerator, MoveNext, Reset und Current verfügt, wird sie mit foreach arbeiten. Das Auslassen der Schnittstellen hat den Vorteil, dass Sie einen Rückgabetyp für Current definieren können, der spezifischer als Object ist. Dadurch wird Typsicherheit bereitgestellt.

Ändern Sie z.B. die folgenden Zeilen im vorherigen Beispiel.


// 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  
        {   }  
    }  
 }  

Da Current eine Zeichenfolge zurückgibt, kann der Compiler erkennen, wenn ein nicht kompatibler Typ in einer foreach-Anweisung verwendet wird, so wie in folgendem Code dargestellt.


// Error: Cannot convert type string to int.  
foreach (int item in f)    

Wenn IEnumerable und IEnumerator ausgelassen werden, besteht der Nachteil darin, dass die Auflistungsklasse nicht länger mit den foreach-Anweisungen oder entsprechenden Anweisungen anderer Common Language Runtime-Sprachen interoperabel ist.

Siehe auch

System.Collections.Generic
C#-Referenz
C#-Programmierhandbuch
Arrays
Sammlungen