Union Types in C#: Schöne Idee — aber wer setzt das im Mittelstand wirklich um?

Milan Jovanović erklärt, warum Union Types in C# 15 ein Gamechanger sind. Aus KMU-Beratungssicht: Die Idee stimmt — aber der Weg dorthin ist für die meisten Betriebe gerade noch vermint.

⚙ KI-Entwurf Dieser Beitrag wurde automatisiert generiert und nicht redaktionell freigegeben. Behandelt ihn entsprechend.

Letzten Herbst saß ich bei einem Maschinenbauer, 180 Mitarbeiter, Standort Schwaben. Der leitende Entwickler zeigt mir stolz ihre interne API für die Auftragsverwaltung. Eine Methode, GetOrder(int id), gibt entweder eine Order zurück — oder wirft eine OrderNotFoundException. Die Exception wird zwei Ebenen weiter oben irgendwo gecatcht, meistens mit einem leeren catch-Block. "Wir wissen, dass das nicht schön ist", sagt er, "aber so haben wir das halt immer gemacht."

Das ist kein Einzelfall. Es ist das Standardmuster in jedem zweiten .NET-Projekt, das mir auf den Tisch kommt. Exceptions als Kontrollfluss, Nullable-Rückgaben, die niemand konsequent prüft, oder bool TryGet-Methoden, bei denen der Aufrufer einfach das out-Ergebnis nimmt und die Rückgabe ignoriert. Der Compiler sagt nichts. Der nächste Entwickler übernimmt das Muster. Der Fehler landet beim Kunden.


Milan Jovanović hat einen sehr lesenswerten Artikel darüber veröffentlicht, was C# 15 mit Union Types ändert — und warum das eine echte Lücke schließt. Die Kurzfassung: Du kannst künftig mit public union Result<T>(T, Exception); explizit deklarieren, dass eine Methode genau diese Typen zurückgibt, nichts anderes. Der Compiler kennt alle Fälle, prüft beim Pattern Matching auf Vollständigkeit und warnt, wenn du einen Case vergisst — auch dann, wenn du später einen neuen Typ zur Union hinzufügst. Keine Laufzeitüberraschungen mehr, keine versteckten Exceptions, keine Nullable-Fallen. Der Artikel zeigt das sauber am Beispiel einer Zahlungsmethoden-Union und einer GetUser-Methode, die statt einer Exception einen NotFound-Record zurückgibt. Das ist saubere Sprache, die die Wahrheit sagt.


Jetzt die Mittelstands-Brille.

Das Timing ist das Problem. C# 15 kommt mit .NET 11. Zum Erscheinungsdatum dieses Artikels ist das ein Preview. Die meisten KMUs, die ich berate, sind auf .NET 6 oder .NET 8 — beides LTS-Versionen, die bewusst gewählt wurden, weil niemand jedes Jahr upgraden will. .NET 11 ist kein LTS. Das heißt: Selbst wenn das Feature sich bis Release nicht mehr ändert (der Artikel selbst warnt, dass die Syntax noch variieren kann), wird es bei einem typischen 40-Mann-Softwarebetrieb frühestens mit .NET 12 ernsthaft evaluiert. Das sind locker zwei Jahre.

Was du heute kannst, ist fast genauso gut. Die OneOf-Library, die Jovanović kurz erwähnt, gibt es seit Jahren auf NuGet. Sie macht exakt das Gleiche — ohne Compiler-Integration, aber funktional äquivalent. In zwei von drei Projekten, wo ich das eingeführt habe, war der entscheidende Effekt nicht das Typsystem. Es war, dass das Team überhaupt anfing, über Rückgabewerte nachzudenken. Ein OneOf<User, NotFound, Unauthorized> als Rückgabetyp zwingt den Aufrufer zur Entscheidung — oder zumindest zur Auseinandersetzung damit. Das kriegst du mit OneOf heute, ohne Preview-Risiko.

Was der Artikel ausblendet, ist die Migrations-Realität. Ein Greenfield-Projekt? Klar, union types von Anfang an einsetzen, wunderbar. Aber die meisten KMU-Codebases sind 8-15 Jahre alt. Da gibt es tausende Methoden, die Exceptions werfen oder null zurückgeben. Den Schnitt auf Union Types zu machen bedeutet: Du brauchst Konventionen, wann du neue Methoden mit Union Types schreibst und wann nicht. Du brauchst Linting oder Reviewprozesse, die verhindern, dass nach drei Monaten wieder jemand eine neue GetSomething-Methode mit Exception schreibt, weil er das Muster nicht gesehen hat. Und du brauchst einen Entwickler, der die Exhaustiveness-Warnings nicht einfach mit _ wegdrückt.

Das ist kein Argument gegen Union Types. Es ist ein Argument dafür, dass das Feature allein nichts löst.


Meine Empfehlung für KMUs, konkret:

Wenn ihr auf .NET 8 seid und ein Team mit fünf oder mehr Entwicklern habt: Schaut euch OneOf an. Nicht für alles — aber für Methoden an Systemgrenzen, also Repository-Layer, externe API-Calls, Parsing. Macht eine interne Konvention: "Methoden, die aus dem Datenbankzugriff zurückkommen, werfen keine Exceptions für Nicht-Funde." Zieht das für drei Monate durch. Dann wisst ihr, ob euer Team das trägt.

Wenn ihr auf .NET 9 oder 10 seid: Guckt, ob .NET 11 LTS wird oder nicht. Stand heute ist es kein LTS. Ich würde Preview-Features in Produktionscode erst einsetzen, wenn das Feature GA ist und die Syntax feststeht. Jovanović selbst schreibt, dass sich da noch was ändern kann.

Wenn ihr ein Greenfield-Projekt auf .NET 11 startet: Ja, Union Types direkt einsetzen. Aber seid ehrlich zu euch: Wie viele KMUs starten 2026 ein echtes Greenfield-Projekt ohne Legacy-Ballast? Ich zähle die auf einer Hand.

Und noch eins, das kein Sprach-Feature löst: Das eigentliche Problem beim Schwaben-Maschinenbauer war nicht der Rückgabetyp von GetOrder. Es war, dass niemand im Team eine explizite Konvention hatte, wann Exceptions okay sind und wann nicht. Die besten Union Types helfen nichts, wenn der nächste Junior-Entwickler einfach eine Exception danebenwirft, weil er das Muster nicht verinnerlicht hat. Sprach-Features können das unterstützen — aber sie ersetzen keine Team-Konvention.


Der vollständige Original-Beitrag von Milan Jovanović: Union Types Are Finally Coming to C#

Lesenswert. Er erklärt das Feature klarer und kompakter als die meisten Preview-Writeups, die ich kenne.


Wenn du dir unsicher bist, ob Union Types, OneOf oder ein anderer Ansatz in eurem spezifischen Codestand der richtige Hebel sind — oder wenn du einfach wissen willst, wo in eurer Fehlerbehandlung die größten Risiken stecken: Buch dir 30 Minuten.

30 Min Klartext-Sparring

— Bernhard