C#8.0: Änderungen bei Schnittstellen und Compiler
In aller Strenge
Wie üblich hat Microsoft der neuen C#-Version einige Spracherweiterungen spendiert. Und der Compiler soll nun auf Programmierfehlern beruhende Null-Referenz-Laufzeitfehler abstellen.
Nachdem 2017 C# 7.0 erschien, gab es erstmals Unterversionen der Programmiersprache (7.1, 7.2, 7.3) mit jeweils nur wenigen Änderungen. Die Hauptversion 8.0 hat Microsoft am 23.09.2019 zusammen mit .NET Core 3.0 und Visual Studio 2019, Version 16.3, veröffentlicht. Grundsätzlich kann man den 8.0-Compiler auch mit dem klassischen .NET Framework einsetzen. Aber – und das ist neu – dort stehen nicht alle neuen Sprachfeatures zur Verfügung, denn einige erfordern Klassen in der .NET-Klassenbibliothek, die im klassischen .NET Framework nicht existieren. Nur in .NET Core, aber nicht in .NET Framework verfügbar sind die in diesem Beitrag behandelten Themen „Standardimplementierungen in Schnittstellen“, „Range und Index“ sowie „asynchrone Streams“.
Microsoft betont, dass die Weiterentwicklung des klassischen .NET Framework abgeschlossen ist, sodass man nicht mehr damit rechnen darf, dass C# 8.0 und folgende Sprachversionen dort jemals vollständig laufen können [1]. C# 8.0 ist komplett nur auf .NET-Implementierungen verfügbar, die dem .NET-Standard 2.1 folgen. Einen Überblick über die .NET-Unterstützung gibt es unter ix.de/z2x7.
Der Compiler trägt die Versionsnummer 3.3. Die Redmonder hatten ihn im Jahr 2015 neu implementiert und dabei die Versionszählung wieder bei 1.0 begonnen. 3.3 ist in Visual Studio 2019 ab Version 16.3, dem .NET Core Software Development Kit ab Version 3.0 und dem Nuget-Paket „Microsoft.Net.Compilers“ enthalten (siehe ix.de/z2x7).
Schon im September 2017 hatte Microsoft für C# 8.0 angekündigt, dass Referenztypen nicht mehr automatisch „nullable“ sein sollen; also fähig, den Wert null anzunehmen. Will der Entwickler es dennoch, soll er es explizit deklarieren müssen. Nach einiger Diskussion hat man sich jedoch dazu entschlossen, diese Neuerung nicht zum Standard, sondern zu einer Option des Compilers zu machen.
Der Compiler bringt dafür drei neue optionale Kontexte mit, also Bereiche im Programmcode, in Codedateien und ganzen Projekten:
- Nullable Warning Context: Der Compiler warnt vor dem Auftreten von Null-Referenz-Laufzeitfehlern bei allen Zugriffen auf Variablen, bei denen möglich oder nicht sichergestellt ist, dass sie nicht null enthalten beziehungsweise der Null-Fall nicht abgefangen wird.
-
Nullable Annotation Context: Referenztypen wie
string
und eigene Klassen sind im Standard nicht mehr „nullable“. Wenn Null-Werte explizit gewünscht sind, ist dies mit dem Fragezeichen bei der Typdeklaration anzuzeigen, zum Beispielstring?
undKlasse?.
Nicht erlaubt sindNullable<string>
undNullable<Klasse>
wie bei den Nullable Value Types. - Nullable Context: Allgemein wird so ein Kontext bezeichnet, der sowohl Warning Context als auch Annotation Context ist, also die Funktionen beider Kontexte in sich vereint.
Die Tabelle „Varianten des Null-Kontextes in C# 8.0“ stellt die drei Kontextarten gegenüber. Das Aktivieren auf Projektebene ist möglich in .csproj-Dateien sowohl für das klassische .NET Framework als auch in den kompakteren .NET-Core-Projektdateien. Listing 1 zeigt an Beispielen die Auswirkungen der drei Kontextarten.
Varianten des Null-Kontextes in C# 8.0 | |||
Nullable Annotation Context | Nullable Warning Context | Nullable Context (Annotation Context + Warning Context) | |
Bedeutung der Deklaration Klasse
| Non-Nullable | Nullable | Non-Nullable |
Bedeutung der Deklaration Klasse?
| Nullable | nicht erlaubt (führt zur Warnung) | Nullable |
Warnung vor Null Reference Exceptions | ein | ja | ja |
Aktivierung auf Projektebene in der .csproj-Datei |
<Nullable>annotations</Nullable>
|
<Nullable>warnings</Nullable>
|
<Nullable>enable</Nullable>
|
Aktivierung im Code |
#nullable enable annotations
|
#nullable enable warnings
|
#nullable enable
|
Deaktivierung im Code |
#nullable disable annotations
|
#nullable disable warnings
|
#nullable disable
|
Zurücksetzung auf Projekteinstellung |
#nullable restore annotations
|
#nullable restore warnings
|
#nullable restore
|
Eine weitere Behandlung des Null-Falls ist hinzugekommen in Form des Operators „Null Coalescing Assignment“ ??=
. Mit ihm kann der Entwickler eine Zuweisung ausführen, wenn eine Variable den Wert null hat. Statt