CodeGym /Kurse /C# SELF /Einführung in Value Tuples

Einführung in Value Tuples

C# SELF
Level 11 , Lektion 1
Verfügbar

1. Einführung

Programmieren ist wie Kofferpacken: Meistens musst du nicht nur einen Gegenstand einpacken, sondern gleich mehrere. Zum Beispiel Socken und ein Ladekabel fürs Handy. Und nur für die temporäre Aufbewahrung von zwei, drei Sachen willst du dir bestimmt keinen neuen Koffer-Klasse kaufen (über Klassen reden wir später noch). Manchmal willst du einfach aus einer Funktion zwei oder drei Werte zurückgeben. Was tun?

Es gibt ein paar alte "Großvater"-Methoden. Zum Beispiel ein Array zurückgeben (int[] arr = {a, b};) oder Felder einer Klasse benutzen, die du nur für eine Funktion deklarierst. Es gibt auch andere, kompliziertere Ansätze, die wir in späteren Lektionen anschauen (out-Parameter oder Übergabe über globale Variablen). Aber eigentlich willst du doch jetzt sofort was Einfaches, Kompaktes und Modernes!

Dafür gibt's seit C# 7 Value Tuples (Value Tuple): Ein superpraktischer und knapper Syntax, um mehrere Werte unterschiedlichen Typs temporär zu bündeln, ohne sich mit eigenen Datentypen rumzuärgern. Das ist nicht nur praktisch, sondern macht den Code auch echt schick.

2. Was sind Tuples (Value Tuples)?

Tuples sind so eine Art Programmierer-Magie, mit der du mehrere verschiedene Werte in eine "Tasche" stecken und zusammen herumtragen kannst. Stell sie dir wie schnelle Notizzettel vor – du musst nicht für jede Kleinigkeit einen eigenen Ordner anlegen!

Value Tuple (System.ValueTuple) ist ein Chamäleon-Struct, das von zwei bis acht Elemente beliebigen Typs aufnehmen kann. Willst du eine Zahl, einen String und einen bool zusammenpacken? Kein Problem! Tuple ist da nicht wählerisch.

Beispiel: Tuple aus verschiedenen Typen erstellen


// tuple — das ist (int, string, bool) - Level, Nickname, online
var tuple = (42, "Krasser_Spieler_2024", true);

Siehst du? Keine Klassen, kein unnötiges Zeremoniell! Einfach in Klammern, Kommas dazwischen – fertig. Das ist wie Fastfood in der Programmierwelt: schnell, praktisch und genau das, was du gerade brauchst.
Und das Beste: Tuples werden "on the fly" direkt im Code erstellt. Perfekt für Situationen, in denen du mal eben was aus einer Funktion zurückgeben oder Daten temporär gruppieren willst. Warum einen riesigen Klassen-Garten anlegen, wenn's auch elegant und einfach geht?

3. Syntax und Basis-Deklaration eines Tuples

Wir starten mit der einfachsten Variante: ohne Namen für die Elemente.

var point = (10, 20);
Console.WriteLine(point.Item1); // 10
Console.WriteLine(point.Item2); // 20
Tuple ohne Namen: Zugriff über Item1, Item2

Hier ist point ein Tuple mit zwei Elementen (int, int). Zugriff auf die Elemente bekommst du über die Felder Item1, Item2 usw. (bis Item7). Wenn das Tuple mehr Elemente hat, landen das achte und weitere im Spezialfeld Rest (dazu gleich mehr). point.Item1 und point.Item2 sind Feldnamen der Struktur ValueTuple<int, int>, die vom Compiler automatisch generiert werden.

Warum var?


(int, int) point = (10, 20);
Typ kann auch explizit angegeben werden

Tipp: var ist praktisch, weil C# den Typ automatisch korrekt ableitet. Aber wenn du betonen willst, dass du mit einem Tuple arbeitest, kannst du den Typ auch explizit angeben.

4. Elemente im Tuple benennen

Mal ehrlich, Item1 und Item2 sind nicht gerade sprechende Namen. Da geht mehr! Dafür gibt's benannte Elemente:

var person = (Name: "Alisa", Age: 20);
Console.WriteLine(person.Name); // Alisa
Console.WriteLine(person.Age);  // 20
Tuple mit benannten Elementen

Jetzt haben die Elemente sinnvolle Namen. Nice! Das ist praktisch für die Lesbarkeit und auch fürs Autocomplete in der IDE.

Kann man Namen und keine Namen mischen?

Ja, C# erlaubt das, aber besser ist es, immer Namen zu vergeben, besonders wenn das Tuple mehr als zwei Elemente hat oder die Werte unterschiedliche Bedeutungen haben:

var data = (42, Name: "Bob", true);
Console.WriteLine(data.Item1); // 42
Console.WriteLine(data.Name);  // Bob
Console.WriteLine(data.Item3); // true

5. Tuples aus Methoden zurückgeben und empfangen

Das häufigste Szenario: Du willst aus einer Methode nicht nur einen Wert zurückgeben, sondern gleich mehrere. Zum Beispiel beim Parsen eines Strings direkt die Zahl und den Erfolgsstatus bekommen.

Beispiel: Summe und Produkt von zwei Zahlen berechnen

Stell dir vor, du sollst eine Funktion schreiben, die zwei Zahlen nimmt und gleichzeitig deren Summe und Produkt zurückgibt. Ohne Tuples müsstest du entweder out-Parameter benutzen (was das ist, schauen wir uns später an) oder extra eine Klasse oder ein Struct dafür bauen (was eigentlich gegen die Idee von Value Tuples als "temporäres Bündeln mehrerer Werte unterschiedlichen Typs, ohne sich mit eigenen Datentypen rumzuärgern" spricht).

Mehrere Werte mit einem Tuple aus einer Methode zurückgeben:


// Methode, die ein Tuple mit zwei Werten zurückgibt: Summe und Produkt
(int sum, int product) CalculateSumAndProduct(int a, int b)
{
    return (a + b, a * b);
}

// Methodenaufruf
var calculationResult = CalculateSumAndProduct(10, 5);

// Ergebnis ausgeben
Console.WriteLine($"Summe: {calculationResult.sum}");
Console.WriteLine($"Produkt: {calculationResult.product}");

6. Einschränkungen und Besonderheiten von Tuples

Alles, was perfekt scheint, hat auch seine Tücken. Lass uns reinschauen.

Anzahl der Elemente

Tuples in C# unterstützen direkt bis zu 7 Elemente. Wenn du mehr brauchst – das achte und weitere landen in einem verschachtelten Tuple (Rest). Aber wenn du das wirklich brauchst, solltest du vielleicht doch über ein Struct oder eine Klasse nachdenken.

var bigTuple = (1, 2, 3, 4, 5, 6, 7, 8);

// .NET erstellt automatisch ein verschachteltes Tuple beim achten Element
Console.WriteLine(bigTuple.Item8); // 8

Mutierbarkeit

ValueTuple ist ein veränderbares Struct! Du kannst jedes Feld nach der Erstellung ändern (aber übertreib's nicht, sonst wird der Code magisch und undurchsichtig).

var t = (a: 1, b: 2);
t.a = 5; // Das geht!

7. Wofür Tuples in echten Projekten und im Vorstellungsgespräch?

Tuples machen es super einfach, mehrere Werte aus einer Methode zurückzugeben, ohne extra Klassen oder Structs zu bauen. Das ist besonders praktisch, wenn du Daten mal eben gruppieren willst – zum Beispiel beim Filtern oder Auswählen aus Collections, beim Testen oder bei temporären Berechnungen.

Außerdem sind Tuples perfekt, um Ergebnisse direkt in mehrere Variablen zu dekonstruieren (z.B. nach einem LINQ-Query), was den Code lesbarer und kompakter macht.

Im Vorstellungsgespräch für eine Junior-Dev-Stelle kommt oft die Frage: „Wie gibst du aus einer Methode mehrere Werte zurück?“ – und die perfekte Antwort ist ValueTuple. Wichtig ist dabei zu wissen, dass das ein Struct mit eingebauter Unterstützung für benannte Elemente und Dekonstruktion ist, im Gegensatz zum alten referenziellen Tuple<T1, T2>.

Wenn du aber mit Daten arbeitest, die lange gespeichert werden oder Teil der Business-Logik sind, oder wenn du mehr als sieben Felder zurückgeben willst, solltest du lieber eine eigene Klasse oder ein Struct mit sinnvollen Properties bauen.

8. Typische Fehler und Stolperfallen

Fehler Nr. 1: Tippfehler bei Tuple-Elementnamen.
Die Felder Item1, Item2 und benannte Elemente werden im Typ ValueTuple gespeichert. Wenn du versehentlich einen falschen Namen verwendest, kompiliert der Code zwar, aber beim Zugriff auf ein nicht existierendes Feld bekommst du entweder zur Laufzeit einen Fehler oder die IDE findet das Property nicht. Immer auf die genaue Schreibweise achten!

Fehler Nr. 2: Dekonstruktion übernimmt nicht die Originalnamen.
Wenn du ein unbenanntes Tuple mit var (first, second) = tuple; dekonstruierst, heißen die neuen Variablen first und second lokal, aber die Originalnamen Item1/Item2 bleiben unverändert. Um Verwirrung zu vermeiden, besser gleich Tuples mit sprechenden Namen deklarieren:

var tuple = (X: 5, Y: 10);
var (x, y) = tuple;  // x == 5, y == 10

Fehler Nr. 3: Die Semantik von struct unterschätzen.
ValueTuple ist ein Struct, das heißt, beim Methodenaufruf oder Zuweisung wird es kopiert. Änderungen innerhalb einer Funktion betreffen nur die lokale Kopie, nicht das Original-Tuple. Wenn du erwartest, dass sich ein Tuple-Element "vor Ort" ändert, achte darauf, dass du mit dem Rückgabewert arbeitest oder Referenztypen verwendest.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION