4 min Lesezeit 30. Sept. 2026

C# Queue und Stack einfach erklärt: So nutzt du sie richtig

Queue (FIFO) und Stack (LIFO) in C# erklärt: Methoden, Unterschiede und praktische Beispiele für Azubis, Studenten und Berufseinsteiger.

Marcel Schmidtpeter Von Marcel Schmidtpeter 30. Sept. 2026
C# Queue und Stack einfach erklärt: So nutzt du sie richtig

Stell dir vor, dein Ausbilder gibt dir die Aufgabe, ein kleines Ticketsystem zu bauen: Support-Anfragen sollen in der Reihenfolge bearbeitet werden, in der sie eingehen. Gleichzeitig soll dein Kollege eine Undo-Funktion für ein Textprogramm bekommen - der letzte Arbeitsschritt muss zuerst rückgängig gemacht werden. Zwei Aufgaben, zwei Datenstrukturen: Queue und Stack. Genau um die geht es hier - und darum, wie du beide in C# richtig einsetzt.

Beide gehören zum Namespace `System.Collections.Generic` und sind generische Collections. Wenn du dabei noch nicht sicher bist, wirf zuerst einen Blick in unseren C# Collections Überblick.

Was ist eine Queue in C#?

Eine Queue (Warteschlange) arbeitet nach dem FIFO-Prinzip: *First In, First Out*. Das Element, das als erstes hineinkommt, kommt auch als erstes wieder heraus. Genau wie an der Supermarkt-Kasse - wer zuerst ansteht, wird zuerst abkassiert.

Die beiden wichtigsten Methoden:

  • `Enqueue(item)`: fügt ein Element am Ende der Schlange an

  • `Dequeue()`: entnimmt das vorderste Element und entfernt es aus der Schlange

csharp
Queue<string> tickets = new Queue<string>();

tickets.Enqueue("Drucker funktioniert nicht");
tickets.Enqueue("Passwort vergessen");
tickets.Enqueue("Monitor flackert");

// Bearbeitung in Eingangsreihenfolge
string erstesTicket = tickets.Dequeue();
Console.WriteLine(erstesTicket); // Drucker funktioniert nicht

Dazu gibt es `Peek()` - damit schaust du dir das vorderste Element an, ohne es zu entfernen. Praktisch, wenn du erst prüfen willst, ob sich die Bearbeitung lohnt.

Merke: `Dequeue()` entfernt das Element, `Peek()` liefert es nur zurück. Die Queue wird bei `Peek()` nicht verändert.

Was ist ein Stack in C#?

Ein Stack (Stapel) arbeitet nach dem LIFO-Prinzip: *Last In, First Out*. Das zuletzt hinzugefügte Element wird als erstes wieder entnommen. Stell dir einen Stapel Teller vor: Du legst Teller oben drauf und nimmst sie auch oben wieder herunter.

Die wichtigsten Methoden:

  • `Push(item)`: legt ein Element oben auf den Stapel

  • `Pop()`: entnimmt das oberste Element und entfernt es vom Stapel

csharp
Stack<string> undoSpeicher = new Stack<string>();

undoSpeicher.Push("Text 'Hallo' eingefuegt");
undoSpeicher.Push("Text 'Welt' eingefuegt");
undoSpeicher.Push("Alles fett formatiert");

// Undo: letzter Schritt zuerst
string letzterSchritt = undoSpeicher.Pop();
Console.WriteLine(letzterSchritt); // Alles fett formatiert

Auch hier gibt es `Peek()` mit derselben Bedeutung wie bei der Queue: nachschauen, ohne zu entnehmen.

Queue vs. Stack: Der direkte Vergleich

Eigenschaft

`Queue<T>`

`Stack<T>`

Prinzip

FIFO (First In, First Out)

LIFO (Last In, First Out)

Hinzufügen

`Enqueue(item)` - hinten

`Push(item)` - oben

Entnehmen

`Dequeue()` - vorn

`Pop()` - oben

Anschauen

`Peek()`

`Peek()`

Typisches Beispiel

Warteschlange, Print-Jobs

Undo/Redo, Browser-History

Merke: `Queue<T>` = Supermarkt-Kasse (wer zuerst kommt, zahlt zuerst). `Stack<T>` = Tellerstapel (was oben liegt, wird zuerst genommen).

Intern sind beide Klassen als Array implementiert - die Queue als sogenanntes Ringpuffer-Array. `Enqueue`, `Dequeue`, `Push` und `Pop` laufen damit amortisiert in konstanter Zeit O(1). Einen Indexzugriff wie bei `List<T>` gibt es dagegen nicht, und `Contains(item)` sucht linear (O(n)) - bei großen Datenmengen also teuer. Details findest du in der offiziellen Microsoft-Dokumentation zu Queue<T> und Stack<T>. Wenn du wissen willst, wann stattdessen eine `LinkedList` sinnvoll ist, hilft dir unser Artikel zu List vs. LinkedList in C# weiter.

Praxisbeispiel: Ein kleines Ticketsystem mit Queue

Hier ein vollständiges, lauffähiges Beispiel, wie du es etwa in einem Ausbildungsprojekt oder einer Studienaufgabe umsetzen könntest:

csharp
using System;
using System.Collections.Generic;

class Program
{
  static void Main()
  {
    Queue<string> warteschlange = new Queue<string>();

    // Tickets gehen ein
    warteschlange.Enqueue("Ticket #1: Login defekt");
    warteschlange.Enqueue("Ticket #2: Drucker offline");
    warteschlange.Enqueue("Ticket #3: VPN bricht ab");

    Console.WriteLine("Offene Tickets: " + warteschlange.Count);

    // Abarbeitung, bis die Schlange leer ist
    while (warteschlange.Count > 0)
    {
      string ticket = warteschlange.Dequeue();
      Console.WriteLine("Bearbeite: " + ticket);
    }

    Console.WriteLine("Offene Tickets: " + warteschlange.Count); // 0
  }
}

Die Ausgabe:

text
Offene Tickets: 3
Bearbeite: Ticket #1: Login defekt
Bearbeite: Ticket #2: Drucker offline
Bearbeite: Ticket #3: VPN bricht ab
Offene Tickets: 0

Die `while`-Schleife mit `Count > 0` ist das Standardmuster, um eine Queue vollständig zu leeren, ohne dass eine Exception fliegt. Das `T` in `Queue<T>` ist übrigens ein Typparameter - mehr dazu in unserem Artikel zu C# Generics.

Welche typischen Fehler passieren bei Queue und Stack?

Drei Fehler sehen wir bei Anfängern immer wieder - alle drei sind leicht zu vermeiden, wenn du sie einmal kennst.

Fehler 1: Dequeue oder Pop auf eine leere Collection

Der Klassiker: Du rufst `Dequeue()` oder `Pop()` auf, obwohl die Collection leer ist. Das Ergebnis ist eine `InvalidOperationException`. Und Vorsicht: Auch `Peek()` auf einer leeren Collection wirft diese Exception. Immer vorher prüfen:

csharp
// Falsch: crasht bei leerer Queue
string ticket = tickets.Dequeue();

// Richtig: erst pruefen, dann entnehmen
if (tickets.Count > 0)
{
  string ticket = tickets.Dequeue();
}

Wie du solche Exceptions sauber behandelst, zeigen wir in C# Exception Handling.

Fehler 2: Elemente während foreach entfernen

Eine `foreach`-Schleife über eine Queue oder einen Stack darf diese nicht verändern. Wer innerhalb der Schleife `Dequeue()` oder `Pop()` aufruft, bekommt eine `InvalidOperationException` geworfen:

csharp
// Falsch: Exception zur Laufzeit
foreach (string t in tickets)
{
  tickets.Dequeue(); // crasht!
}

// Richtig: mit while und Count arbeiten
while (tickets.Count > 0)
{
  string t = tickets.Dequeue();
}

Warum? Weil der Enumerator der Collection über ihren aktuellen Zustand wacht - sobald sich die Datenstruktur ändert, gilt sie als ungültig. Mehr dazu in IEnumerable und foreach in C#.

Fehler 3: Die falsche Datenstruktur wählen

Eine `List<T>` kann alles, was Queue und Stack auch können - technisch gesehen. Aber sie verschleiert deine Absicht. Wenn dein Code `queue[5]` erlaubt, obwohl semantisch nur „vorne entnehmen" erlaubt sein soll, entsteht ein Bug-Risiko. Die Wahl der passenden Datenstruktur dokumentiert dein Design. Wer `Queue<T>` sieht, weiß sofort: Hier geht es um Reihenfolge beim Hinein- und Herausholen.

Merke: Wähle die Datenstruktur nach der Bedeutung aus, nicht nach dem, was gerade funktioniert. Queue = Reihenfolge, Stack = Umkehrung.

Übungstipp: Bau eine Undo-Funktion

Nimm einen einfachen Konsolen-Editor: Der Nutzer gibt Textzeilen ein, mit dem Befehl `undo` wird die letzte Zeile gelöscht, mit `print` wird alles ausgegeben. Speichere die Zeilen in einem `Stack<string>`, pushe jede neue Zeile und pope bei `undo`. Das schaffst du in unter 30 Minuten - und du hast LIFO nicht nur gelesen, sondern gelebt. Danach erweiterst du das Ganze um eine `Queue<string>` für einen Befehlsverlauf.

FAQ: Häufige Fragen zu Queue und Stack in C#

Was ist der Unterschied zwischen Queue und Stack in C#?

Eine Queue arbeitet nach FIFO (First In, First Out) - das erste Element kommt zuerst heraus. Ein Stack arbeitet nach LIFO (Last In, First Out) - das letzte Element kommt zuerst heraus.

Wann nutze ich eine Queue, wann einen Stack?

Queue, wenn die Reihenfolge des Eintreffens zählt (Tickets, Druckaufträge, Nachrichtenwarteschlangen). Stack, wenn es auf das zuletzt Geschehene ankommt (Undo, Back-Navigation, Klammern prüfen beim Parser).

Was passiert bei Dequeue() oder Pop() auf einer leeren Collection?

Es wird eine `InvalidOperationException` geworfen. Prüfe vorher mit `Count > 0` oder fange die Exception ab. Dasselbe gilt übrigens für `Peek()`.

Was macht Peek() bei Queue und Stack?

`Peek()` gibt das nächste Element zurück (bei der Queue das vorderste, beim Stack das oberste), ohne es zu entfernen. Die Collection bleibt unverändert.

Sind Queue und Stack threadsicher?

Nein, `Queue<T>` und `Stack<T>` aus `System.Collections.Generic` sind nicht threadsicher. Für parallele Producer-Consumer-Szenarien nutzt du stattdessen `System.Collections.Concurrent.ConcurrentQueue<T>`. Mehr zu Nebenläufigkeit in C# async await Task.

Fazit

Queue und Stack gehören in C# zu den einfachsten und gleichzeitig nützlichsten Datenstrukturen. Die Essenz: Queue = FIFO für Reihenfolge, Stack = LIFO für Umkehrung. Mit `Enqueue`/`Dequeue` bzw. `Push`/`Pop` bedienst du beide intuitiv - achte nur auf die leere Collection und verändere nichts während `foreach`. Diese Themen kommen übrigens regelmäßig in IHK-Prüfungen und Universitätsvorlesungen zu Algorithmen und Datenstrukturen vor.

Wenn du bei C#-Grundlagen, Prüfungsvorbereitung oder deinen ersten Berufsjahren Unterstützung brauchst: Bei study-it.education findest du individuelle Nachhilfe genau für Azubis, Studenten und Quereinsteiger - mit Erklärungen auf deinem Level.


Erstgespräch · 0 € · 30 min

Brauchst du jemand, der das mit dir durchgeht?

Statt nochmal lesen: 30 min mit einem Senior-Dev.

Kostenloses Erstgespräch buchen →
Über den Autor
Marcel Schmidtpeter
Marcel Schmidtpeter

Queue (FIFO) und Stack (LIFO) in C# erklärt: Methoden, Unterschiede und praktische Beispiele für Azubis, Studenten und Berufseinsteiger.

marcel.schmidtpeter@study-it.education →
Weiterlesen

Mehr Lesestoff