.NET 10 Upgrade und plötzlich fühlt sich Wartung angenehm an
Kennst du das Gefühl, wenn ein Framework Upgrade eigentlich riesig klingt, du aber innerlich hoffst, dass es einfach nur ein paar Paket Updates sind und gut? Genau so bin ich an .NET 10 rangegangen. Und ja, .NET 10 ist nicht irgendein Release, sondern LTS. Release war am 11. November 2025, Support läuft bis November 2028. Das ist der Teil, der sich nach solider Planung anfühlt und nicht nach Glücksspiel.
Im Projekt selbst war das Upgrade fast schon langweilig. Target Framework hoch, Pakete nachziehen, Tests laufen lassen, fertig. Klar, ein paar Warnungen tauchen auf, aber nichts, was einen den Kaffee kalt werden lässt. Performance und Tooling fühlen sich reif an, und Microsoft positioniert das Release auch genau so. Stabil, LTS, mit spürbaren Verbesserungen.
Der Code war brav, die Pipeline eher nicht
Und dann kam der Teil, den man gern vergisst: Build und Release. Lokal alles grün, im CI plötzlich Rot. Nicht weil .NET 10 komisch wäre, sondern weil die Azure Runner und auch manche Azure Release Tasks das neue SDK noch nicht automatisch mitbringen. Das sieht man gerade dann, wenn man auf Microsoft hosted Agents vertraut oder ältere Release Pipelines pflegt, die seit Jahren niemand anfassen wollte.
Die pragmatische Lösung war erstaunlich simpel: SDK aktiv installieren. In Azure Pipelines geht das sauber mit UseDotNet. Damit ziehst du dir die gewünschte SDK Version in den Job und entkoppelst dich ein Stück weit vom Agent Image Stand. Microsoft dokumentiert den Task ziemlich klar, inklusive Cache Verhalten und Versionsangabe.
Dass das kein Einzelfall ist, sieht man auch in der Praxis: Entwickler berichten, dass ihre Build Agents noch nicht auf .NET 10 standen und erst eine explizite SDK Installation den Build wieder stabil gemacht hat.
Nebenbei, kleiner Tipp aus der Kategorie “spart Nerven”: eine saubere global.json hilft, wenn Teams parallel arbeiten und nicht jeder Rechner zufällig dasselbe SDK zieht. Das ist kein Glamour Thema, aber es verhindert diese leisen Versionsdrifts, die später viel Zeit fressen.
Alles gut, bis auf eine Sache, die noch kommt
Unterm Strich war das Upgrade angenehm. Der eigentliche Reibungspunkt war weniger .NET 10 selbst, sondern das Drumherum in Azure. Sobald das SDK bewusst im Pipeline Schritt sitzt, wird es wieder ruhig.
Was ich aber nicht unter den Teppich kehre: C# 14 bringt neue Span Konvertierungen, und damit ändert sich in bestimmten Szenarien die Overload Resolution. Das kann ausgerechnet bei Contains auffallen, speziell wenn Expression Trees interpretiert kompiliert werden. Plötzlich bindet array.Contains nicht mehr an Enumerable.Contains, sondern an MemoryExtensions.Contains, und dann knallt es zur Laufzeit. Microsoft beschreibt das samt Beispiel und Workarounds ziemlich direkt.
Genau da setze ich im nächsten Blogpost an: Expression Visitors, warum solche Bindings in Queries und Providern heikel sind, und welche Fixes sich sauber anfühlen, ohne dass man überall nervöse Casts verteilt.