Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Der Zweck von Nullwerte zulassenden Warnungen besteht darin, die Wahrscheinlichkeit zu minimieren, dass Ihre Anwendung bei der Ausführung eine System.NullReferenceException auslöst. Um dieses Ziel zu erreichen, verwendet der Compiler statische Analysen und gibt Warnungen aus, wenn Ihr Code Konstrukte enthält, die zu Nullverweisausnahmen führen können. Sie stellen dem Compiler Informationen für seine statische Analyse bereit, indem Sie Typanmerkungen und Attribute anwenden. Diese Anmerkungen und Attribute beschreiben die NULL-Zulässigkeit von Argumenten, Parametern und Membern Ihrer Typen. In diesem Artikel lernen Sie verschiedene Techniken kennen, um die nullablen Warnungen zu behandeln, die der Compiler aus seiner statischen Analyse generiert. Die hier beschriebenen Techniken gelten für allgemeinen C#-Code. Informationen zum Arbeiten mit Nullable-Verweistypen und Entity Framework Core finden Sie unter Arbeiten mit Nullable-Verweistypen.
Nullable-Verweistypen, einschließlich der Operatoren ? und !, sind nur zulässig, wenn der Nullable-Kontext auf enable oder annotations gesetzt ist. Sie können den nullfähigen Kontext mithilfe der NullableCompileroption in Ihrer Projektdatei oder mit dem #nullable Pragma im Quellcode festlegen.
In diesem Artikel werden die folgenden Compilerwarnungen behandelt:
- CS8597 - Der ausgelöste Wert darf NULL sein.
- CS8598 - Der Unterdrückungsoperator ist in diesem Kontext nicht zulässig.
- CS8600 - Null-Literal oder möglichen Null-Wert in Typ ohne NULL-Zulässigkeit konvertieren.
- CS8601 - Mögliche Nullverweiszuweisung.
- CS8602 - Dereferenzierung eines möglichen Nullverweises.
- CS8603 - Mögliche Nullverweisrückgabe.
- CS8604 - Mögliches Nullverweisargument für den Parameter.
- CS8605 - Entpacken eines möglichen Nullwertes.
-
CS8607 - Ein möglicher NULL-Wert darf nicht für einen mit
[NotNull]oder[DisallowNull]markierten Typ verwendet werden. - CS8608 - NULL-Zulässigkeit von Verweistypen in Typ stimmt nicht mit überschriebenem Mitglied überein.
- CS8609 - NULL-Zulässigkeit von Verweistypen im Rückgabetyp stimmt nicht mit dem überschriebenen Member überein.
- CS8610 - NULL-Zulässigkeit von Verweistypen in Typ-Parametern stimmt nicht mit überschriebenem Member überein.
- CS8611 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht nicht der Deklaration der partiellen Methode.
- CS8612 - NULL-Zulässigkeit von Verweistypen in Typ stimmt nicht mit implizit implementiertem Mitglied überein.
- CS8613 - NULL-Zulässigkeit von Verweistypen im Rückgabetyp stimmt nicht mit implizit implementiertem Member überein.
- CS8614 - NULL-Zulässigkeit von Verweistypen im Typ des Parameters stimmt nicht mit dem implizit implementierten Member überein.
- CS8615 - NULL-Zulässigkeit von Verweistypen in Typ stimmt nicht mit implementiertem Mitglied überein.
- CS8616 - NULL-Zulässigkeit von Verweistypen im Rückgabetyp stimmt nicht mit implementiertem Mitglied überein.
- CS8617 - NULL-Zulässigkeit von Verweistypen im Typ des Parameters stimmt nicht mit dem implementierten Mitglied überein.
- CS8618 - Non-Nullable-Variable muss beim Verlassen des Konstruktors einen Nicht-NULL-Wert enthalten. Erwägen Sie die Deklaration als „Nullwerte zulassend“.
- CS8619 - NULL-Zulässigkeit von Verweistypen in Wert stimmt nicht mit Zieltyp überein.
- CS8620 - Das Argument kann aufgrund von Unterschieden bei der NULL-Zulässigkeit von Verweistypen nicht für den Parameter verwendet werden.
- CS8621 - NULL-Zulässigkeit von Verweistypen im Rückgabetyp stimmt nicht mit dem Zieldelegat überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
- CS8622 - NULL-Zulässigkeit von Verweistypen im Typ des Parameters stimmt nicht mit dem Zieldelegaten überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
-
CS8623 - Die explizite Anwendung von
System.Runtime.CompilerServices.NullableAttributeist nicht zulässig. - CS8624 - Argument kann aufgrund von Unterschieden in der NULL-Zulässigkeit von Verweistypen nicht als Ausgabe verwendet werden.
- CS8625 - Ein NULL-Literal kann nicht in einen Non-Nullable-Verweistyp konvertiert werden.
- CS8628 - In der Objekterstellung kann kein nullwertbarer Verweistyp verwendet werden.
- CS8629 - Werttyp mit NULL-Zulässigkeit kann Null sein.
- CS8631 - Der Typ kann nicht als Typparameter in einem generischen Typ oder einer Methode verwendet werden.
-
CS8632 - Die Annotation für Verweistypen mit NULL-Zulässigkeit sollte nur in Code innerhalb eines
#nullableAnnotationskontexts verwendet werden. - CS8633 - Die NULL-Zulässigkeit in Einschränkungen für den Typparameter der Methode entspricht nicht den Einschränkungen für den Typparameter der Schnittstellenmethode. Verwenden Sie stattdessen eine explizite Schnittstellenimplementierung.
- CS8634 - Der Typ kann nicht als Typparameter in einem generischen Typ oder einer Methode verwendet werden. NULL-Zulässigkeit des Typ-Arguments entspricht nicht der Einschränkung „Klasse“.
-
CS8636 - Ungültige Option für
/nullable; mussdisable,enable,warningsoderannotationssein -
CS8637 - Erwartet
enable,disableoderrestore - CS8639 - Der Typeof-Operator kann nicht für einen nullfähigen Verweistyp verwendet werden.
- CS8643 - Die NULL-Zulässigkeit von Verweistypen im expliziten Schnittstellenspezifizierer entspricht nicht der vom Typ implementierten Schnittstelle.
- CS8644 - Typ implementiert kein Schnittstellenmitglied. Die NULL-Zulässigkeit von Verweistypen in der vom Basistyp implementierten Schnittstelle stimmt nicht überein.
- CS8645 - Mitglied ist bereits in der Schnittstellenliste auf Typ mit unterschiedlicher NULL-Zulässigkeit von Verweistypen aufgeführt.
- CS8655 - Der Switch-Ausdruck verarbeitet einige NULL-Eingaben nicht (nicht umfassend).
- CS8667 - Partielle Methodendeklarationen weisen eine inkonsistente NULL-Zulässigkeit in Einschränkungen für den Typparameter auf.
- CS8670 - Der Objekt- oder Auflistungsinitialisierer dereferenziert implizit einen Member, der möglicherweise NULL ist.
- CS8714 - Der Typ kann nicht als Typparameter in einem generischen Typ oder einer Methode verwendet werden. NULL-Zulässigkeit des Typarguments entspricht nicht der Einschränkung „Nicht-Null“.
- CS8762 - Der Parameter muss beim Beenden einen Wert ungleich NULL aufweisen.
-
CS8763 - Eine mit
[DoesNotReturn]gekennzeichnete Methode darf nicht zurückgegeben werden. - CS8764 - NULL-Zulässigkeit des Rückgabetyps stimmt nicht mit dem überschriebenen Member überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
- CS8765 - NULL-Zulässigkeit des Typs des Parameters stimmt nicht mit dem überschriebenen Member überein (möglicherweise wegen der NULL-Zulässigkeitsattribute).
- CS8766 - NULL-Zulässigkeit von Verweistypen im Rückgabetyp von stimmt nicht mit implizit implementiertem Member überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
- CS8767 - NULL-Zulässigkeit von Verweistypen im Typ des Parameters von stimmt nicht mit dem implizit implementierten Member überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
- CS8768 - NULL-Zulässigkeit von Verweistypen im Rückgabetyp stimmt nicht mit dem implementierten Member überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
- CS8769 - NULL-Zulässigkeit von Verweistypen im Typ des Parameters stimmt nicht mit dem implementierten Member überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
-
CS8770 - Methode fehlt
[DoesNotReturn]-Anmerkung für implementiertes oder überschriebenes Mitglied. - CS8774 - Mitglied muss beim Beenden einen Nicht-Null-Wert haben.
- CS8776 - Mitglied kann in diesem Attribut nicht verwendet werden.
- CS8775 - Mitglied muss beim Beenden einen Nicht-Null-Wert haben.
- CS8777 - Der Parameter muss beim Beenden einen Wert ungleich NULL aufweisen.
- CS8819 - NULL-Zulässigkeit von Verweistypen im Rückgabetyp stimmt nicht mit der Deklaration einer Teilmethode überein.
- CS8824 - Der Parameter muss beim Beenden einen Wert ungleich NULL aufweisen, weil der Parameter nicht NULL ist.
- CS8825 - Der Rückgabewert muss ungleich NULL sein, weil der Parameter nicht NULL ist.
- CS8847 - Der Switch-Ausdruck verarbeitet einige NULL-Eingaben nicht (nicht umfassend). Ein Muster mit einer when-Klausel kann jedoch erfolgreich mit diesem Wert übereinstimmen.
Hinweis
Die statische Analyse kann nicht immer ableiten, in welcher Reihenfolge, in einem bestimmten Szenario, auf Methoden zugegriffen wird und ob die Methode erfolgreich abgeschlossen wird, ohne eine Ausnahme zu auslösen. Diese bekannten Fallstricke werden im Abschnitt " Bekannte Fallstricke " gut beschrieben.
Sie behandeln fast alle Warnungen mit einer von fünf Techniken:
- Konfigurieren des nullablen Kontexts.
- Hinzufügen der erforderlichen NULL-Überprüfungen.
- Hinzufügen oder Entfernen von
?oder!nullfähigen Anmerkungen. - Hinzufügen von Attributen, die die NULL-Semantik beschreiben.
- Richtiges Initialisieren von Variablen.
Wenn Sie neu in der Verwendung nullable Verweistypen sind, liefert die Übersicht über nullable Verweistypen Hintergrundinformationen dazu, was nullable Verweistypen lösen und wie sie funktionieren, um vor möglichen Fehlern in Ihrem Code zu warnen. Sie können auch die Anleitungen zum Migrieren zu nullfähigen Verweistypen überprüfen, um mehr über das Aktivieren von nullablen Verweistypen in einem vorhandenen Projekt zu erfahren.
Konfigurieren Sie den löschbaren Kontext
Die folgenden Warnungen deuten darauf hin, dass Sie den nullfähigen Kontext nicht richtig festgelegt haben:
-
CS8632 - Die Anmerkung für nullable Verweistypen sollte nur im Code innerhalb eines
#nullableAnmerkungskontexts verwendet werden. -
CS8636 - Ungültige Option für
/nullable; mussdisable,enable,warningsoderannotationssein -
CS8637 - Erwartet
enable,disable, oderrestore -
CS8668 - Erwartet
warnings,annotations, oder Ende der Direktive
Um den nullfähigen Kontext richtig festzulegen, haben Sie zwei Optionen:
Konfiguration auf Projektebene: Fügen Sie das
<Nullable>Element zu Ihrer Projektdatei hinzu:<PropertyGroup> <Nullable>enable</Nullable> </PropertyGroup>Konfiguration auf Dateiebene: Verwenden Sie
#nullablePräprozessordirektiven in Ihrem Quellcode:#nullable enable
Der Nullable-Kontext weist zwei unabhängige Flags auf, die verschiedene Aspekte regeln:
-
Anmerkungskennzeichen: Steuert, ob Sie
?nullbare Verweistypen deklarieren und!einzelne Warnungen unterdrücken können. - Warnungskennzeichnung: Steuert, ob der Compiler Nullbarkeitswarnungen ausgibt.
Ausführliche Informationen zu nullfähigen Kontexten und Migrationsstrategien finden Sie unter:
Falsche Anmerkungssyntax
Diese Fehler und Warnungen deuten darauf hin, dass die Verwendung von ! oder ? Anmerkung inkorrekt ist.
- CS8598 - Der Unterdrückungsoperator ist in diesem Kontext nicht zulässig.
-
CS8623 - Die explizite Anwendung von
System.Runtime.CompilerServices.NullableAttributeist nicht zulässig. - CS8628 - In der Objekterstellung kann kein nullwertbarer Verweistyp verwendet werden.
- CS8639 - Der typeof-Operator kann nicht für einen Nullable-Referenztyp verwendet werden.
Die ? Anmerkung in einer Deklaration gibt an, dass die Variable null sein kann. Es gibt keinen anderen Laufzeittyp an. Beide Deklarationen sind derselbe Laufzeittyp:
string s1 = "a string";
string? s2 = "another string";
Dies ? ist ein Hinweis auf den Compiler für die Erwartung von NULL-Werten.
Die ! Anmerkung eines Ausdrucks gibt an, dass Sie wissen, dass der Ausdruck sicher ist und angenommen werden sollte, dass er nicht NULL ist.
- Sie müssen diese Anmerkungen verwenden, nicht das System.Runtime.CompilerServices.NullableAttribute in Ihrem Code.
- Da es
?sich um eine Anmerkung handelt, nicht um einen Typ, können Sie sie nicht mittypeofAusdrücken odernewAusdrücken verwenden. - Der
!Operator kann nicht auf einen Variablenausdruck oder eine Methodengruppe angewendet werden. - Der Operator
!kann nicht links von einem Operator für den Mitgliederzugriff, wieobj.Field!.Method(), angewendet werden.
Mögliche Dereferenzierung von NULL
Diese Gruppe von Warnungen informiert Sie, dass Sie eine Variable, deren NULL-Zustand maybe-null ist, dereferenzieren. Diese Warnungen sind:
- CS8602 - Dereferenzierung eines möglichen Nullverweises.
- CS8670 - Der Objekt- oder Auflistungsinitialisierer dereferenziert implizit einen Member, der möglicherweise NULL ist.
Der folgende Code veranschaulicht ein Beispiel für jede der vorherigen Warnungen:
class Container
{
public List<string>? States { get; set; }
}
internal void PossibleDereferenceNullExamples(string? message)
{
Console.WriteLine(message.Length); // CS8602
var c = new Container { States = { "Red", "Yellow", "Green" } }; // CS8670
}
Im vorherigen Beispiel liegt die Warnung daran, dass der Container, c, möglicherweise einen NULL-Wert für die States Eigenschaft hat. Durch das Zuweisen neuer Zustände zu einer Auflistung, die möglicherweise NULL ist, wird die Warnung verursacht.
Um diese Warnungen zu entfernen, müssen Sie Code hinzufügen, um den NULL-Zustand dieser Variablen in not-null zu ändern, bevor Sie sie dereferenzieren. Die Warnung vor dem Initialisierungsprogramm für Sammlungen kann schwieriger zu erkennen sein. Der Compiler erkennt, dass die Auflistung maybe-null ist, wenn der Initialisierer ihr Elemente hinzufügt.
In vielen Fällen können Sie diese Warnungen beheben, indem Sie überprüfen, ob eine Variable nicht NULL ist, bevor Sie sie dereferenzieren. Sehen Sie sich das folgende Beispiel an, das eine NULL-Prüfung hinzufügt, bevor Sie den message Parameter ableiten:
void WriteMessageLength(string? message)
{
if (message is not null)
{
Console.WriteLine(message.Length);
}
}
Im folgenden Beispiel wird der Sicherungsspeicher für States initialisiert und die set-Zugriffsmethode entfernt. Consumer der Klasse können den Inhalt der Sammlung ändern, und der Speicher für die Sammlung ist nie null:
class Container
{
public List<string> States { get; } = new();
}
Andere Fälle, in denen Sie diese Warnungen erhalten, könnten falsch positiv sein. Möglicherweise verfügen Sie über eine private Hilfsprogrammmethode, die auf NULL testet. Der Compiler weiß nicht, dass die Methode eine NULL-Überprüfung durchführt. Betrachten Sie das folgende Beispiel, das eine private Hilfsmethode, IsNotNull, verwendet:
public void WriteMessage(string? message)
{
if (IsNotNull(message))
Console.WriteLine(message.Length);
}
Der Compiler warnt, dass Sie möglicherweise ein null dereferenzieren, wenn Sie die Eigenschaft message.Length schreiben, da die statische Analyse bestimmt, dass messagenull sein könnte. Sie wissen, dass IsNotNull eine NULL-Überprüfung bereitstellt und dass, wenn es true zurückgibt, der Null-Zustand von messagenicht null sein sollte. Sie müssen dem Compiler diese Fakten mitteilen. Eine Möglichkeit besteht darin, den NULL-toleranten Operator (!) zu verwenden. Sie können die WriteLine-Anweisung so ändern, dass sie dem folgenden Code entspricht:
Console.WriteLine(message!.Length);
Der NULL-tolerante Operator macht den Ausdruck not-null, auch wenn er ohne Anwendung von ! war. In diesem Beispiel besteht eine bessere Lösung darin, der Signatur von IsNotNull ein Attribut hinzuzufügen:
private static bool IsNotNull([NotNullWhen(true)] object? obj) => obj != null;
Das System.Diagnostics.CodeAnalysis.NotNullWhenAttribute informiert den Compiler, dass das für den obj-Parameter verwendete Argument not-null ist, wenn die Methode true zurückgibt. Wenn die Methode false zurückgibt, weist das Argument den gleichen NULL-Zustand wie vor dem Aufruf der Methode auf.
Tipp
Es gibt eine Vielzahl von Attributen, mit denen Sie beschreiben können, wie Sich Ihre Methoden und Eigenschaften auf den NULL-Zustand auswirken. Informationen dazu finden Sie im Artikel der Sprachreferenz zu Attributen für die statische Analyse des NULL-Zustands.
Zum Beheben einer Warnung zur Deferenzierung einer maybe-null-Variablen gibt es drei Techniken:
- Fügen Sie eine fehlende NULL-Überprüfung hinzu.
- Fügen Sie NULL-Analyseattribute für APIs hinzu, um die statische Analyse des NULL-Zustands des Compilers zu beeinflussen. Diese Attribute informieren den Compiler, wenn ein Rückgabewert oder Argument nach dem Aufrufen der Methode maybe-null oder not-null sein kann.
- Wenden Sie den Nullvergebungsoperator
!auf den Ausdruck an, der den Zustand Nicht-Nullerzwingt.
Mögliche Zuweisung von NULL zu einem Non-Nullable-Verweis
Dieser Satz von Warnungen benachrichtigt Sie, dass Sie eine Variable mit Non-Nullable-Typ einem Ausdruck zuweisen, dessen NULL-Zustand maybe-null ist. Diese Warnungen sind:
- CS8597 - Der ausgelöste Wert darf NULL sein.
- CS8600 - Null-Literal oder möglicher Null-Wert in Typ ohne Null-Zulässigkeit konvertieren.
- CS8601 - Mögliche Nullverweiszuweisung.
- CS8603 - Mögliche Nullverweisrückgabe.
- CS8604 - Mögliches Nullverweisargument für den Parameter.
- CS8605 - Entpacken eines möglichen Nullwertes.
- CS8625 - Ein NULL-Literal kann nicht in einen Non-Nullable-Verweistyp konvertiert werden.
- CS8629 - Ein Werttyp, der NULL zulässt, kann NULL sein.
Der Compiler gibt diese Warnungen aus, wenn Sie versuchen, einer Non-Nullable-Variablen einen Ausdruck zuzuweisen, der maybe-null ist. Zum Beispiel:
string? TryGetMessage(int id) => "";
string msg = TryGetMessage(42); // Possible null assignment.
Die verschiedenen Warnungen geben Details zum Code an, z. B. Zuweisung, Unboxing-Zuweisung, Rückgabeanweisungen, Argumente für Methoden und Auslösen von Ausdrücken.
Sie können eine von drei Aktionen ausführen, um diese Warnungen zu beheben. Eine besteht darin, die ?-Anmerkung hinzuzufügen, um die Variable zu einem Nullable-Verweistyp zu machen. Diese Änderung kann andere Warnungen verursachen. Durch Änderung einer Variablen von einem Non-Nullable-Verweis in einen Nullable-Verweis wird der standardmäßige NULL-Zustand von not-null in maybe-null geändert. Die statische Analyse des Compilers findet Instanzen, in denen Sie eine Variable ableiten, die möglicherweise null ist.
Die anderen Aktionen weisen den Compiler an, dass die rechte Seite der Zuweisung not-null ist. Der Ausdruck auf der rechten Seite kann vor der Zuweisung auf NULL geprüft werden, wie im folgenden Beispiel gezeigt:
string notNullMsg = TryGetMessage(42) ?? "Unknown message id: 42";
Die obigen Beispiele veranschaulichen die Zuweisung zum Rückgabewert einer Methode. Sie kommentieren die Methode (oder Eigenschaft), um anzugeben, wann eine Methode einen Wert ungleich NULL zurückgibt.
System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute gibt häufig an, dass ein Rückgabewert not-null ist, wenn ein Eingabeargument not-null ist. Eine andere Alternative ist das Hinzufügen des NULL-toleranten Operators ! auf der rechten Seite:
string msg = TryGetMessage(42)!;
Zum Beheben einer Warnung für die Zuweisung eines maybe-null-Ausdrucks zu einer not-null-Variablen gibt es vier Techniken:
- Ändern Sie die linke Seite der Zuweisung in einen Nullable-Typ. Diese Aktion kann neue Warnungen verursachen, wenn Sie diese Variable dereferenzieren.
- Führen Sie vor der Zuweisung eine NULL-Überprüfung durch.
- Versehen Sie die API mit einer Anmerkung, die die rechte Seite der Zuweisung erzeugt.
- Fügen Sie den NULL-toleranten Operator auf der rechten Seite der Zuweisung hinzu.
Non-Nullable-Verweis nicht initialisiert
Dieser Satz von Warnungen benachrichtigt Sie, dass Sie eine Variable mit Non-Nullable-Typ einem Ausdruck zuweisen, dessen NULL-Zustand maybe-null ist. Diese Warnungen sind:
- CS8618 - Non-Nullable-Variable muss beim Verlassen des Konstruktors einen Nicht-NULL-Wert enthalten. Erwägen Sie die Deklaration als „Nullwerte zulassend“.
- CS8777 - Der Parameter muss beim Beenden einen Wert ungleich NULL aufweisen.
Betrachten Sie beispielsweise die folgende Klasse:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Weder FirstName noch LastName werden garantiert initialisiert. Wenn dieser Code neu ist, sollten Sie die öffentliche Schnittstelle ändern. Das vorangehende Beispiel kann wie folgt aktualisiert werden:
public class Person
{
public Person(string first, string last)
{
FirstName = first;
LastName = last;
}
public string FirstName { get; set; }
public string LastName { get; set; }
}
Wenn Sie vor dem Festlegen des Namens ein Person-Objekt erstellen müssen, können Sie die Eigenschaften mit einem Non-Null-Standardwert initialisieren:
public class Person
{
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
}
Eine andere Alternative ist, diese Mitglieder in Verweistypen NULL-Zulässigkeit zu ändern. Die Person-Klasse könnte wie folgt definiert werden, wenn null für den Namen zulässig sein soll:
public class Person
{
public string? FirstName { get; set; }
public string? LastName { get; set; }
}
Vorhandener Code erfordert manchmal andere Änderungen, um den Compiler über die Nullsemantik für diese Member zu informieren. Sie könnte mehrere Konstruktoren haben und Ihre Klasse hat eine private Hilfsmethode, die ein oder mehrere Mitglieder initialisiert. Sie können den Initialisierungscode in einen einzelnen Konstruktor verschieben und sicherstellen, dass alle Konstruktoren den Code mit dem gemeinsamen Initialisierungscode aufrufen. Sie können auch die Attribute System.Diagnostics.CodeAnalysis.MemberNotNullAttribute und System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute verwenden. Diese Attribute informieren den Compiler darüber, dass ein Element nach dem Zurückgeben der Methode nicht null ist. Im folgenden Code ist ein Beispiel für jede Methode dargestellt. Die Person-Klasse verwendet einen gemeinsamen Konstruktor, der von allen anderen Konstruktoren aufgerufen wird. Die Student-Klasse verfügt über eine Hilfsmethode, die mit dem System.Diagnostics.CodeAnalysis.MemberNotNullAttribute-Attribut als Anmerkung versehen ist:
using System.Diagnostics.CodeAnalysis;
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public Person() : this("John", "Doe") { }
}
public class Student : Person
{
public string Major { get; set; }
public Student(string firstName, string lastName, string major)
: base(firstName, lastName)
{
SetMajor(major);
}
public Student(string firstName, string lastName) :
base(firstName, lastName)
{
SetMajor();
}
public Student()
{
SetMajor();
}
[MemberNotNull(nameof(Major))]
private void SetMajor(string? major = default)
{
Major = major ?? "Undeclared";
}
}
Schließlich können Sie den NULL-toleranten Operator verwenden, um anzugeben, dass ein Member in einem anderen Code initialisiert wird. Betrachten Sie für ein weiteres Beispiel die folgenden Klassen, die ein Entity Framework Core-Modell darstellen:
public class TodoItem
{
public long Id { get; set; }
public string? Name { get; set; }
public bool IsComplete { get; set; }
}
public class TodoContext : DbContext
{
public TodoContext(DbContextOptions<TodoContext> options)
: base(options)
{
}
public DbSet<TodoItem> TodoItems { get; set; } = null!;
}
Die DbSet-Eigenschaft wird mit null! initialisiert. Dies teilt dem Compiler mit, dass die Eigenschaft auf einen not-null-Wert festgelegt ist. Tatsächlich führt base DbContext die Set-Initialisierung durch. Die statische Analyse des Compilers greift dies nicht auf. Weitere Informationen zur Verwendung von Nullable-Verweistypen und Entity Framework Core finden Sie im Artikel Arbeiten mit Nullable-Verweistypen in EF Core.
Zum Beheben einer Warnung für die Nicht-Initialisierung eines Non-Nullable-Members gibt es vier Techniken:
- Ändern Sie die Konstruktoren oder Feldinitialisierer, damit alle Non-Nullable-Member initialisiert werden.
- Ändern Sie mindestens ein Member in Nullable-Typen.
- Versehen Sie Hilfsmethoden mit Anmerkungen, um anzugeben, welche Member zugewiesen sind.
- Fügen Sie einen Initialisierer zu
null!hinzu, um anzugeben, dass der Member in einem anderen Code initialisiert wird.
Nicht übereinstimmende Nullability-Deklaration
Viele Warnungen weisen darauf hin, dass zwischen Signaturen für Methoden, Delegaten oder Typparameter keine Übereinstimmung in Bezug auf die NULL-Zulässigkeit besteht.
- CS8608 - NULL-Zulässigkeit von Verweistypen in Typ stimmt nicht mit überschriebenem Mitglied überein.
- CS8609 - NULL-Zulässigkeit von Verweistypen im Rückgabetyp stimmt nicht mit überschriebenem Member überein.
- CS8610 - NULL-Zulässigkeit von Verweistypen im Typ-Parameter stimmt nicht mit dem überschriebenen Member überein.
- CS8611 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht nicht der Deklaration der partiellen Methode.
- CS8612 - NULL-Zulässigkeit von Verweistypen in Typ stimmt nicht mit implizit implementiertem Mitglied überein.
- CS8613 - NULL-Zulässigkeit von Verweistypen im Rückgabetyp stimmt nicht mit implizit implementiertem Member überein.
- CS8614 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht nicht dem implizit implementierten Member.
- CS8615 - NULL-Zulässigkeit von Verweistypen in Typ stimmt nicht mit implementiertem Mitglied überein.
- CS8616 - NULL-Zulässigkeit von Verweistypen im Rückgabetyp stimmt nicht mit implementiertem Member überein.
- CS8617 - NULL-Zulässigkeit von Verweistypen im Typ des Parameters stimmt nicht mit dem implementierten Mitglied überein.
- CS8619 - NULL-Zulässigkeit von Verweistypen in Wert stimmt nicht mit Zieltyp überein.
- CS8620 - Das Argument kann aufgrund von Unterschieden bei der NULL-Zulässigkeit von Verweistypen nicht für den Parameter verwendet werden.
- CS8621 - Die NULL-Zulässigkeit von Verweistypen im Rückgabetyp stimmt nicht mit dem Zieldelegat überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
- CS8622 - NULL-Zulässigkeit von Verweistypen im Typ des Parameters stimmt nicht mit dem Zieldelegaten überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
- CS8624 - Das Argument kann aufgrund von Unterschieden bei der NULL-Zulässigkeit von Verweistypen nicht als Ausgabe verwendet werden.
- CS8631 - Der Typ kann nicht als Typparameter in einem generischen Typ oder einer Methode verwendet werden.
- CS8633 - Die NULL-Zulässigkeit in Einschränkungen für den Typparameter der Methode entspricht nicht den Einschränkungen für den Typparameter der Schnittstellenmethode. Verwenden Sie stattdessen eine explizite Schnittstellenimplementierung.
- CS8634 - Der Typ kann nicht als Typparameter im generischen Typ oder in der generischen Methode verwendet werden. Die NULL-Zulässigkeit des Typarguments entspricht nicht der class-Einschränkung.
- CS8643 - Die NULL-Zulässigkeit von Verweistypen im expliziten Schnittstellenspezifizierer entspricht nicht der vom Typ implementierten Schnittstelle.
- CS8644 - Typ implementiert kein Schnittstellenmitglied. Die NULL-Zulässigkeit von Verweistypen in der vom Basistyp implementierten Schnittstelle stimmt nicht überein.
- CS8645 - Mitglied ist bereits in der Schnittstellenliste auf Typ mit unterschiedlicher NULL-Zulässigkeit von Verweistypen aufgeführt.
- CS8667 - Partielle Methodendeklarationen weisen eine inkonsistente NULL-Zulässigkeit in Einschränkungen für den Typparameter auf.
- CS8714 - Der Typ kann nicht als Typparameter in einem generischen Typ oder einer Methode verwendet werden. NULL-Zulässigkeit des Typarguments entspricht nicht der Einschränkung „Nicht-Null“
- CS8764 - NULL-Zulässigkeit des Rückgabetyps stimmt nicht mit dem überschriebenen Member überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
- CS8765 - Die NULL-Zulässigkeit des Typs eines Parameters stimmt nicht mit dem überschriebenen Member überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
- CS8766 - NULL-Zulässigkeit von Verweistypen im Rückgabetyp von stimmt nicht mit implizit implementiertem Member überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
- CS8767 - NULL-Zulässigkeit von Verweistypen im Typ des Parameters von stimmt nicht mit dem implizit implementierten Member überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
- CS8768 - NULL-Zulässigkeit von Verweistypen im Rückgabetyp stimmt nicht mit dem implementierten Member überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
- CS8769 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters stimmt nicht mit dem implementierten Member überein (möglicherweise aufgrund von NULL-Zulässigkeitsattributen).
- CS8819 - NULL-Zulässigkeit von Verweistypen im Rückgabetyp stimmt nicht mit der Deklaration einer Teilmethode überein.
Im folgenden Code wird CS8764 veranschaulicht:
public class B
{
public virtual string GetMessage(string id) => string.Empty;
}
public class D : B
{
public override string? GetMessage(string? id) => default;
}
Das obige Beispiel veranschaulicht eine virtual-Methode in einer Basisklasse und eine override-Methode mit unterschiedlicher NULL-Zulässigkeit. Die Basisklasse gibt eine Non-Nullable-Zeichenfolge zurück, die abgeleitete Klasse gibt aber eine Nullable-Zeichenfolge zurück. Wenn string und string? umgekehrt werden, wäre dies zulässig, da die abgeleitete Klasse restriktiver ist. Ebenso sollten Parameterdeklarationen übereinstimmen. Parameter in der override-Methode können NULL zulassen, auch wenn die Basisklasse dies nicht tut.
In anderen Situationen können diese Warnungen generiert werden. Es besteht ein Missverhältnis bei der Deklaration einer Schnittstellenmethode und ihrer Implementierung. Oder ein Delegatentyp und der Ausdruck für diesen Delegat unterscheiden sich. Ein Typparameter und das Typargument unterscheiden sich in der Nullierbarkeit.
Aktualisieren Sie die entsprechende Deklaration, um diese Warnungen zu beheben.
Code entspricht nicht der Attributdeklaration
In den vorangehenden Abschnitten wurde erläutert, wie Sie Attribute für nullable statische Analysen verwenden können, um den Compiler über die Nullsemantik Ihres Codes zu informieren. Der Compiler gibt eine Warnung aus, wenn der Code die Zusagen dieses Attributs nicht einhält:
-
CS8607 - Ein möglicher NULL-Wert darf nicht für einen mit
[NotNull]oder[DisallowNull]markierten Typ verwendet werden. -
CS8763 - Eine mit
[DoesNotReturn]gekennzeichnete Methode darf nicht zurückgegeben werden. -
CS8770 - Methode fehlt
[DoesNotReturn]Anmerkung, um implementiertes oder überschriebenes Mitglied zu finden. - CS8774 - Mitglied muss beim Beenden einen Nicht-Null-Wert haben.
- CS8775 - Mitglied muss beim Beenden einen Nicht-Null-Wert haben.
- CS8776 - Mitglied kann in diesem Attribut nicht verwendet werden.
- CS8777 - Der Parameter muss beim Beenden einen Wert ungleich NULL aufweisen.
- CS8824 - Der Parameter muss beim Beenden einen Wert ungleich NULL aufweisen, weil der Parameter nicht NULL ist.
- CS8825 - Der Rückgabewert muss ungleich NULL sein, weil der Parameter nicht NULL ist.
Sehen Sie sich die folgende Methode an:
public bool TryGetMessage(int id, [NotNullWhen(true)] out string? message)
{
message = null;
return true;
}
Der Compiler erzeugt eine Warnung, da der message-Parameter null zugewiesen ist, und die Methode true zurückgibt. Das NotNullWhen-Attribut gibt an, dass nicht passieren sollte.
Um diese Warnungen zu beheben, aktualisieren Sie Ihren Code so, dass er den Erwartungen der angewendeten Attribute entspricht. Sie können die Attribute oder den Algorithmus ändern.
Vollständige Switch-Ausdrücke
Switch-Ausdrücke müssen vollständig sein, was bedeutet, dass alle Eingabewerte verarbeitet werden müssen. Auch bei Non-Nullable-Verweistypen muss der null-Wert berücksichtigt werden. Der Compiler gibt Warnungen aus, wenn der NULL-Wert nicht behandelt wird:
- CS8655 - Der Switch-Ausdruck verarbeitet einige NULL-Eingaben nicht (nicht umfassend).
- CS8847 - Der Switch-Ausdruck verarbeitet einige NULL-Eingaben nicht (nicht umfassend). Ein Muster mit einer when-Klausel kann jedoch erfolgreich mit diesem Wert übereinstimmen.
Der folgende Beispielcode veranschaulicht diese Bedingung:
int AsScale(string status) =>
status switch
{
"Red" => 0,
"Yellow" => 5,
"Green" => 10,
{ } => -1
};
Der Eingabeausdruck ist ein string, kein string?. Der Compiler generiert diese Warnung weiterhin. Das { }-Muster behandelt alle Nicht-NULL-Werte, stimmt aber nicht mit nullüberein. Um diese Fehler zu beheben, können Sie entweder einen expliziten null-Fall hinzufügen oder das { } durch das _-Muster (Verwerfen) ersetzen. Das Verwurfsmuster stimmt sowohl mit null als auch mit jedem anderen Wert überein.