.NET 8.0 (.NET 8)

Eintrag zuletzt aktualisiert am: 17.03.2024

.NET 8.0 ist der Nachfolger von .NET 7.0, der am 14. November 2023 erschienen ist.

Fakten zu .NET 8.0

Versionsgeschichte inkl. Vorabversionen

  • Preview 1 am 21.2.2023
  • Preview 2 am 14.3.2023
  • Preview 3 am 11.4.2023
  • Preview 4 am 16.5.2023
  • Preview 5 am 13.6.2023
  • Preview 6 am 11.7.2023
  • Preview 7 am 8.8.2023
  • Release Candidate 1 am 12.9.2023 mit Go-Live-Lizenz
  • Release Candidate 2 am 10.10.2023 mit Go-Live-Lizenz
  • RTM-Version am 14.11.2023

Neues zum AOT-Compiler

Der im Jahr 2022 in .NET 7.0 eingeführte, aber dort noch auf Konsolenanwendungen beschränkte Ahead-of-Timer-Compiler "Native AOT" kann in .NET 8.0 nun auch Worker Services, gRPC-Dienste und ASP.NET Core WebAPIs (aber nur, wenn diese als Minimal-APIs angelegt sind) übersetzen. Datenbankzugriffe sind nur per ADO.NET (DataReader, DataSet, Command etc) möglich; Entity Framework Core funktioniert noch nicht mit dem AOT-Compiler.

Bei dotnet new gibt es einen neuen Parameter: --aot, z.B.
  • Konsolenanwendung: dotnet new console --aot
  • Minimal WebAPI: dotnet new api --aot
  • gRPC: dotnet new grpc --aot
  • Worker Service: dotnet new worker --aot

Neuerungen im .NET 8.0 SDK

Löschen verwaister Workloads
dotnet workload clean: Löscht nur verwaiste Workloads
dotnet workload clean --all: Alle Workloads löschen

Kompaktere und farbige Ausgabe bei Build: Terminal Logger statt Console Logger (in Windows Terminal, nicht in alter Windows-Konsole!)
dotnet build /tl oder msbuild /tl

Sicherheitswarnungen vor NuGet-Paketen beim Build aktivieren
<NuGetAudit>true</NuGetAudit>
<NuGetAuditLevel>moderate</NuGetAuditLevel> (low, moderate, high, critical)

Nun automatisch Release-Kompilierung bei dotnet publish und dotnet pack
Debug-Kompilierung weiterhin möglich auf Wunsch: dotnet publish -c debug bzw. dotnet pack -c debug

Optionale neue Zusammenfassung von /bin /obj /publish per Eintrag in Directory.Build.props
<ArtifactsPath>$(MSBuildThisFileDirectory)artifacts</ArtifactsPath>

Erstellen einer Container-Datei ohne Veröffentlichung bei Registry
dotnet publish -p PublishProfile=DefaultContainer -p ContainerArchiveOutputPath=t:\meinblazorimage.tar.gz -p:ContainerBaseImage=mcr.microsoft.com/dotnet/aspnet:8.0-alpine

Neuigkeiten in der .NET-Klassenbibliothek in .NET 8.0

  • Neue Validierungsannotationen im Namensraum System.ComponentModel.DataAnnotations, z.B. [AllowedValues], [DeniedValues] und [Base64String] und Erweiterungen bei [Range] und [Length]
  • Eingefrorene Objektmengen: FrozenSet<T> und FrozenDictionary<T, T> im neuen Namensraum System.Collections.Frozen, die Elemente schneller liefern als andere verfügbare Objektmengen
  • Neue Zufallsfunktionen in der Klasse System.Random: Zufallsreihenfolge mit Random.Shared.Shuffle() und

Zufallsauswahl via Random.Shared.GetItems()
  • Neue Methoden zum Auslösen von Fehlern in Methodenparametern, z.B. ArgumentOutOfRangeException.ThrowIfZero(), ArgumentOutOfRangeException.ThrowIfNegative(), ArgumentOutOfRangeException.ThrowIfNegativeOrZero() und ArgumentOutOfRangeException.ThrowIfGreaterThan()
  • Neue Code-Analyzer und Refactoring-Funktionen, z.B. hinsichtlich der Verwendung von Equals() statt Case-Insensitive-Vergleichen mit ToLower()/ToUpper(), StartsWith() statt IndexOf() == 0 und Length/Count statt Any()
  • Plattformneutrale Privilegien-Abfrage mit System.Environment.IsPrivilegedProcess
  • Dependency Injection mit Schlüsseln: services.AddKeyedSingleton<T1, T2>("Name") und serviceProvider.GetKeyedService<T1>("Name")
  • Zeitabstraktion mit der neuen abstrakten Klasse System.TimeProvider für Tests mit Zeitangaben
  • Methoden Parse() und TryParse() in Klasse System.Net.IPNetwork
  • Source-Generator für die Interoperabilität mit dem Component Object Model (COM): [GeneratedComInterface] und [GeneratedComClass] im Namensraum System.Runtime.InteropServices.Marshalling
  • Razor-Template-Rendering außerhalb von Blazor in beliebigen .NET-Anwendungen mit der Klasse Microsoft.AspNetCore.Components.Web.HtmlRenderer im NuGet-Paket Microsoft.AspNetCore.Components.Web

Neues in System.Text.Json 8.0

  • Serialisierung neuerer Datentypen: Half, Int128 und UInt128 sowie Memory<T> und ReadOnlyMemory<T>
  • Zusätzliche JSON-Daten wurden bei der Deserialisierung bisher ignoriert. Nun neu: Annotation [JsonUnmappedMemberHandling(JsonUnmappedMemberHandling.Disallow)] oder

Eigenschaft UnmappedMemberHandling.Disallow im Objekt JsonSerializerOptions
  • Enumeration JsonNamingPolicy für Namenskonventionen (z.B. für FullName): CamelCase (bisher Standard): fullName, KebabCaseLower: full-name, KebabCaseUpper: FULL-NAME, SnakeCaseLower: fullname und SnakeCaseUpper: FULLNAME
  • Serialisierung in bestehende Objekte ohne Setter (siehe dazu auch Bug: https://github.com/dotnet/runtime/issues/92877) JsonObjectCreationHandling.Populate / [JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]
  • Deserialisierung in nicht-öffentliche Mitglieder via Konstruktor mit [JsonConstructor] und [JsonInclude]
  • Alle Daten-Mitglieder aus Interface-Hierarchien verwenden beachtet
  • Bei JsonArray nun Ienumerable, was Aufzählung mit foreach und Language Integrated Query (LINQ) ermöglicht
  • JsonNode aus Stream: JsonNode node = await JsonNode.ParseAsync(stream);
  • Die Klasse JsonNode hat neue Methoden wie DeepClone() und DeepEquals() erhalten
  • Source Generator unterstützt nun auch

alle Optionen wie Reflection-basierte Serialisierung (z.B. String Enums)
die in C# 9.0 eingeführten Init-Only-Properties + die in C# 11.0 eingeführten Required Properties
<JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault>
Reflection-Versuch  Laufzeitfehler:
  • Prüfen im Code mit: if (JsonSerializer.IsReflectionEnabledByDefault) { … }
  • Analyzer warnt vor dem Performanceverlust bei immer neuen Instanzen von JsonSerializerOptions

Verbesserungen für GUI-Frameworks in .NET 8.0

Bei Windows Forms hat Microsoft die in .NET 7.0 noch experimentell eingeführte verbesserte Datenbindung mit Datenkontexten und Command-Pattern in .NET 8.0 produktionsreif gemacht. Über SystemIcons.GetStockIcon() können Entwicklerinnen und Entwickler jetzt die in Windows integrierten Symbole in eigene Anwendungen integrieren.

Die Windows Presentation Foundation (WPF), die in den letzten .NET-Versionen keinerlei nennenswerte Verbesserung erhielt, bekam in .NET 8.0 einen neuen Dialog zum Öffnen von Ordnern (Klasse Microsoft.Win32.OpenFolderDialog). Zudem können Entwicklerinnen und Entwickler nun eine GPU-basiertes Hardware-Rendering anstelle des Software-Rendering für WPF-Anwendungen, die per Remote Desktop Protocol (RDP) übertragen werden:
<ItemGroup>
<RuntimeHostConfigurationOption Include=" Switch.System.Windows.Media.EnableHardwareAccelerationInRdp " Value="true" />
</ItemGroup>
Dies ist eine Funktion, die viele WPF-Anwender seit den Anfangstagen des GUI-Frameworks im Jahr 2006 forderten.

Bei dem im Vergleich zu Windows Forms und WPF noch jungen Cross-Platform-GUI-Framework .NET MAUI hat sich Microsoft auf die Fehlerbehebung und Leistungsoptimierung konzentriert, was das Framework auch dringend nötig hatte. Daneben gibt es noch wenige neue Funktionen: In .NET MAUI 8.0 funktionieren nun auch Layouts mit Rechts-nach-Links-Ausrichtung. Menüeinträge in .NET MAUI können jetzt einen Tastatur-Shortcut besitzen. Für den Mauszeiger gibt es in .NET MAUI die neuen Ereignisse PointerPressed() und PointerReleased(). .NET MAUI 8.0 arbeitet nun auch mit Xcode-Version 15 und Android API-Version 34 zusammen.