Auflösen von Nullable-Warnungen

In diesem Artikel werden die folgenden Compilerwarnungen behandelt:

  • CS8597 - Der ausgelöste Wert darf NULL sein.
  • CS8600 - Das NULL-Literal oder ein möglicher NULL-Wert wird in einen Non-Nullable-Typ konvertiert.
  • CS8601 - Mögliche Nullverweiszuweisung.
  • CS8602 - Dereferenzierung eines möglichen Nullverweises.
  • CS8603 - Mögliche Nullverweisrückgabe.
  • CS8604 - Mögliches Nullverweisargument für den Parameter.
  • CS8605 - Unboxing eines möglichen NULL-Werts.
  • CS8607 - Ein möglicher NULL-Wert darf nicht für einen mit [NotNull] oder [DisallowNull] markierten Typ verwendet werden.
  • CS8608 - Die NULL-Zulässigkeit von Verweistypen im Typ entspricht nicht dem außer Kraft gesetzten Member.
  • CS8609 - Die NULL-Zulässigkeit von Verweistypen im Rückgabetyp entspricht nicht dem außer Kraft gesetzten Member.
  • CS8610 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht nicht dem außer Kraft gesetzten Member.
  • CS8611 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht nicht der Deklaration der partiellen Methode.
  • CS8612 - Die NULL-Zulässigkeit von Verweistypen im Typ entspricht nicht dem implizit implementierten Member.
  • CS8613 - Die NULL-Zulässigkeit von Verweistypen im Rückgabetyp entspricht nicht dem implizit implementierten Member.
  • CS8614 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht nicht dem implizit implementierten Member.
  • CS8615 - Die NULL-Zulässigkeit von Verweistypen im Typ entspricht nicht dem implementierten Member.
  • CS8616 - Die NULL-Zulässigkeit von Verweistypen im Rückgabetyp entspricht nicht dem implementierten Member.
  • CS8617 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht nicht dem implementierten Member.
  • CS8618 - Non-Nullable-Variable muss beim Verlassen des Konstruktors einen Nicht-NULL-Wert enthalten. Erwägen Sie die Deklaration als „Nullwerte zulassend“.
  • CS8619 - Die NULL-Zulässigkeit von Verweistypen im Wert entspricht nicht dem Zieltyp.
  • 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 entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem Zieldelegaten.
  • CS8622 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem Zieldelegaten.
  • CS8624 - Das Argument kann aufgrund von Unterschieden bei der NULL-Zulässigkeit von Verweistypen nicht als Ausgabe verwendet werden.
  • CS8625 - Ein NULL-Literal kann nicht in einen Non-Nullable-Verweistyp konvertiert werden.
  • CS8629 - Ein Werttyp, der NULL zulässt, kann NULL sein.
  • CS8631 - Der Typ kann nicht als Typparameter im generischen Typ oder in der generischen Methode verwendet werden. Die NULL-Zulässigkeit des Typarguments entspricht nicht dem Einschränkungstyp.
  • 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 - Der Typ implementiert den Schnittstellenmember nicht. Die NULL-Zulässigkeit von Verweistypen in der vom Basistyp implementierten Schnittstelle stimmt nicht überein.
  • CS8645 - Member wird bereits mit einer anderen NULL-Zulässigkeit oder abweichenden Verweistypen in der Schnittstellenliste für den Typ 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 im generischen Typ oder in der generischen Methode verwendet werden. Die NULL-Zulässigkeit des Typarguments entspricht nicht der notnull-Einschränkung.
  • CS8762 - Der Parameter muss beim Beenden einen Wert ungleich NULL aufweisen.
  • CS8763 - Eine mit [DoesNotReturn] gekennzeichnete Methode darf nicht zurückgegeben werden.
  • CS8764 - Die NULL-Zulässigkeit des Rückgabetyps entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem überschriebenen Member.
  • CS8765 - Die NULL-Zulässigkeit des Typs des Parameters entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem überschriebenen Member.
  • CS8766 - Die NULL-Zulässigkeit von Verweistypen im Rückgabetyp entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem implizit implementierten Member.
  • CS8767 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem implizit implementierten Member.
  • CS8768 - Die NULL-Zulässigkeit von Verweistypen im Rückgabetyp entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem implementierten Member.
  • CS8769 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem implementierten Member.
  • CS8770 - n der Methode fehlt die Anmerkung [DoesNotReturn] für den Abgleich mit dem implementierten oder überschriebenen Member.
  • CS8774 - Der Member muss beim Beenden einen Wert ungleich NULL aufweisen.
  • CS8776 - Der Member kann in diesem Attribut nicht verwendet werden.
  • CS8775 - Der Member muss beim Beenden einen Wert ungleich NULL aufweisen.
  • CS8777 - Der Parameter muss beim Beenden einen Wert ungleich NULL aufweisen.
  • CS8819 - Die NULL-Zulässigkeit von Verweistypen im Rückgabetyp entspricht nicht der Deklaration der partiellen Methode.
  • 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.

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 über Konstrukte verfügt, die zu NULL-Verweisausnahmen 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 für die Behandlung von Nullable-Warnungen kennen, 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.

Sie können fast alle Warnungen mit einer von vier Techniken behandeln:

  • Hinzufügen der erforderlichen NULL-Überprüfungen.
  • Hinzufügen der Nullable-Anmerkungen ? oder !.
  • Hinzufügen von Attributen, die die NULL-Semantik beschreiben.
  • Richtiges Initialisieren von Variablen.

Mögliche Dereferenzierung von NULL

Diese Gruppe von Warnungen informiert Sie, dass Sie eine Variable, deren NULL-Zustandmaybe-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 obigen Beispiel ist die Warnung darauf zurückzuführen, dass Container, c, für die Eigenschaft States einen NULL-Wert aufweisen kann. 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 des Auflistungsinitialisierers 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. Im Folgenden wird vor der Dereferenzierung des message-Parameters eine NULL-Überprüfung hinzufügt:

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 Vorkommen dieser Warnungen können falsch positiv sein. Möglicherweise verfügen Sie über eine private Hilfsmethode, die auf NULL prüft. 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 gibt eine Warmung mit dem Hinweis aus, Sie beim Schreiben der Eigenschaft message.Length u. U. NULL dereferenzieren, da die statische Analyse bestimmt, dass message möglicherweise null sein kann. Vielleicht wissen Sie, dass IsNotNull eine NULL-Überprüfung ermöglicht, und wenn true zurückgegeben wird, sollte der NULL-Zustand von messagenot-null sein. 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 !maybe-null 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 NULL-toleranten Operator ! auf den Ausdruck an, um den Zustand auf not-null zu zwingen.

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-Zustandmaybe-null ist. Diese Warnungen sind:

  • CS8597 - Der ausgelöste Wert darf NULL sein.
  • CS8600 - Das NULL-Literal oder ein möglicher NULL-Wert wird in einen Non-Nullable-Typ konvertiert.
  • CS8601 - Mögliche Nullverweiszuweisung.
  • CS8603 - Mögliche Nullverweisrückgabe.
  • CS8604 - Mögliches Nullverweisargument für den Parameter.
  • CS8605 - Unboxing eines möglichen NULL-Werts.
  • 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. 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 kann Vorkommen finden, in denen Sie eine Variable dereferenzieren, die maybe-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 können die Methode (oder Eigenschaft) mit einer Anmerkung versehen, um anzugeben, wann eine Methode einen not-null-Wert 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 führt möglicherweise zu neuen Warnungen, wenn Sie die betreffende 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-Zustandmaybe-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“.
  • CS8762 - 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 obige Beispiel könnte 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 kann sein, diese Member in Nullable-Verweistypen 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 möglicherweise andere Änderungen, um den Compiler über die NULL-Semantik für diese Member zu informieren. Möglicherweise haben Sie mehrere Konstruktoren erstellt, und die Klasse verfügt über eine private Hilfsmethode, die Member 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 Member not-null ist, nachdem die Methode aufgerufen wurde. 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 - Die NULL-Zulässigkeit von Verweistypen im Typ entspricht nicht dem außer Kraft gesetzten Member.
  • CS8609 - Die NULL-Zulässigkeit von Verweistypen im Rückgabetyp entspricht nicht dem außer Kraft gesetzten Member.
  • CS8610 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht nicht dem außer Kraft gesetzten Member.
  • CS8611 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht nicht der Deklaration der partiellen Methode.
  • CS8612 - Die NULL-Zulässigkeit von Verweistypen im Typ entspricht nicht dem implizit implementierten Member.
  • CS8613 - Die NULL-Zulässigkeit von Verweistypen im Rückgabetyp entspricht nicht dem implizit implementierten Member.
  • CS8614 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht nicht dem implizit implementierten Member.
  • CS8615 - Die NULL-Zulässigkeit von Verweistypen im Typ entspricht nicht dem implementierten Member.
  • CS8616 - Die NULL-Zulässigkeit von Verweistypen im Rückgabetyp entspricht nicht dem implementierten Member.
  • CS8617 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht nicht dem implementierten Member.
  • CS8619 - Die NULL-Zulässigkeit von Verweistypen im Wert entspricht nicht dem Zieltyp.
  • 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 entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem Zieldelegaten.
  • CS8622 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem Zieldelegaten.
  • 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 im generischen Typ oder in der generischen Methode verwendet werden. Die NULL-Zulässigkeit des Typarguments entspricht nicht dem Einschränkungstyp.
  • 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 - Der Typ implementiert den Schnittstellenmember nicht. Die NULL-Zulässigkeit von Verweistypen in der vom Basistyp implementierten Schnittstelle stimmt nicht überein.
  • CS8645 - Member wird bereits mit einer anderen NULL-Zulässigkeit oder abweichenden Verweistypen in der Schnittstellenliste für den Typ 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 im generischen Typ oder in der generischen Methode verwendet werden. Die NULL-Zulässigkeit des Typarguments entspricht nicht der notnull-Einschränkung.
  • CS8764 - Die NULL-Zulässigkeit des Rückgabetyps entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem überschriebenen Member.
  • CS8765 - Die NULL-Zulässigkeit des Typs des Parameters entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem überschriebenen Member.
  • CS8766 - Die NULL-Zulässigkeit von Verweistypen im Rückgabetyp entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem implizit implementierten Member.
  • CS8767 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem implizit implementierten Member.
  • CS8768 - Die NULL-Zulässigkeit von Verweistypen im Rückgabetyp entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem implementierten Member.
  • CS8769 - Die NULL-Zulässigkeit von Verweistypen im Typ des Parameters entspricht (möglicherweise aufgrund von Attributen für die NULL-Zulässigkeit) nicht dem implementierten Member.
  • CS8819 - Die NULL-Zulässigkeit von Verweistypen im Rückgabetyp entspricht nicht der Deklaration der partiellen Methode.

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. Möglicherweise gibt es einen Konflikt in der Deklaration einer Schnittstellenmethode und der Implementierung dieser Methode. Oder ein Delegattyp und der Ausdruck für diesen Delegat können nicht übereinstimmen. Ein Typparameter und das Typargument können sich in der NULL-Zulässigkeit unterscheiden.

Aktualisieren Sie die entsprechende Deklaration, um diese Warnungen zu beheben.

Code entspricht nicht der Attributdeklaration

In den obigen Abschnitten wurde erläutert, wie Sie -Attribute für die statische Nullable-Analyse verwenden können, um den Compiler über die NULL-Semantik 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 - Der Methode fehlt die Anmerkung [DoesNotReturn] für den Abgleich mit dem implementierten oder überschriebenen Member.
  • CS8774 - Der Member muss beim Beenden einen Wert ungleich NULL aufweisen.
  • CS8775 - Der Member muss beim Beenden einen Wert ungleich NULL aufweisen.
  • CS8776 - Der Member 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 Verwerfen-Muster passt sowohl auf Null als auch auf jeden anderen Wert.