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 <xref:System.Collections.Generic.IEnumerable%601> unterstützt, finden Sie unter Iterators (Iteratoren).

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 <xref:System.Collections.IEnumerator> und <xref:System.Collections.IEnumerable> implementieren, hätte das Codebeispiel die Enumerationsmethoden des Arrays (<xref:System.Collections.IEnumerable.GetEnumerator%2A>, <xref:System.Collections.IEnumerator.MoveNext%2A>, <xref:System.Collections.IEnumerator.Reset%2A> und <xref:System.Collections.IEnumerator.Current%2A>) verwenden können, anstatt sie in der Klasse Tokens 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 <xref:System.Collections.IEnumerable> und <xref:System.Collections.IEnumerator> implementieren, um mit foreach kompatibel zu sein. Wenn die Klasse über die erforderlichen Elemente <xref:System.Collections.IEnumerable.GetEnumerator%2A>, <xref:System.Collections.IEnumerator.MoveNext%2A>, <xref:System.Collections.IEnumerator.Reset%2A> und <xref:System.Collections.IEnumerator.Current%2A> 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 <xref:System.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 <xref:System.Collections.IEnumerator> und foreach ausgelassen werden, besteht der Nachteil darin, dass die Auflistungsklasse nicht länger mit den <xref:System.Collections.IEnumerable>-Anweisungen oder entsprechenden Anweisungen anderer Common Language Runtime-Sprachen interoperabel ist.

Siehe auch

<xref:System.Collections.Generic>
C#-Referenz
C#-Programmierhandbuch
Arrays
Sammlungen