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

 

Veröffentlicht: Juli 2016

Die neueste Dokumentation zu Visual Studio 2017 RC finden Sie unter Visual Studio 2017 RC Documentation (Dokumentation zu Visual Studio 2017 RC).

Im folgenden Codebeispiel wird das Erstellen einer nicht generischen Auflistungsklasse veranschaulicht, die mit foreach verwendet werden kann. Im Beispiel wird eine Zeichenfolgentokenizerklasse definiert.

System_CAPS_ICON_note.jpg Hinweis

Dieses Beispiel entspricht nur in den Fällen der empfohlenen Vorgehensweise, in denen keine generische Auflistungsklasse verwendet werden kann. Ein Beispiel für das Implementieren einer typsicheren generischen Auflistungsklasse, die IEnumerable<T> unterstützt, finden Sie unter Iteratoren.

Im Beispiel verwendet das folgende Codesegment die Tokens-Klasse, um den Satz "This is a sample sentence." unter Verwendung von " " und "-" als Trennzeichen in Tokens aufzulösen. Anschließend werden diese Tokens mithilfe einer foreach-Anweisung angezeigt.

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

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

Intern verwendet die Tokens-Klasse ein Array, um die Tokens zu speichern. Da Arrays IEnumerator und IEnumerable implementieren, hätten im Codebeispiel auch die Enumerationsmethoden (GetEnumerator, MoveNext, Reset und Current) des Arrays verwendet werden können, statt sie in der Tokens-Klasse zu definieren. Die Methodendefinitionen wurden in das Beispiel aufgenommen, um zu erläutern, wie sie definiert werden und was die einzelnen Definitionen bewirken.

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 Member GetEnumerator, MoveNext, Reset und Current verfügt, ist sie mit foreach kompatibel. Wenn Sie die Schnittstellen weglassen, hat dies den Vorteil, dass Sie einen Rückgabetyp für Current definieren können, der spezifischer als Object ist. Dies bietet Typsicherheit.

Ändern Sie beispielsweise 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, ob in einer foreach-Anweisung ein nicht kompatibler Typ verwendet wird, wie im folgenden Code gezeigt.

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

Der Nachteil beim Weglassen von IEnumerable und IEnumerator besteht darin, dass die Auflistungsklasse nicht mehr mit den foreach-Anweisungen oder entsprechenden Anweisungen anderer Common Language Runtime-Sprachen verwendet werden kann.

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

Anzeigen: