Résoudre les avertissements nullables

Cet article traite des avertissements suivantes du compilateur :

  • CS8597 - La valeur levée est peut-être null.
  • CS8600 - Conversion de littéral ayant une valeur null ou d’une éventuelle valeur null en type non nullable.
  • CS8601 - Possible affectation d’une référence null.
  • CS8602 - Déréférencement d’une référence possiblement null.
  • CS8603 - Retour d’une possible référence null.
  • CS8604 - Possible argument de référence null pour le paramètre.
  • CS8605 - Conversion unboxing d’une valeur possiblement null.
  • CS8607 - Une possible valeur null ne peut pas être utilisée pour un type marqué avec [NotNull] ou [DisallowNull]
  • CS8608 - La nullabilité des types référence dans le type ne correspond pas au membre surchargé.
  • CS8609 - La nullabilité des types référence dans le type de retour ne correspond pas au membre surchargé.
  • CS8610 - La nullabilité des types référence dans le type de paramètre ne correspond pas au membre surchargé.
  • CS8611 - La nullabilité des types référence dans le type de paramètre ne correspond pas à la déclaration de méthode partielle.
  • CS8612 - La nullabilité des types référence dans le type ne correspond pas au membre implémenté implicitement.
  • CS8613 - La nullabilité des types référence dans le type de retour ne correspond pas au membre implémenté implicitement.
  • CS8614 - La nullabilité des types référence dans le type de paramètre ne correspond pas au membre implémenté implicitement.
  • CS8615 - La nullabilité des types référence dans le type ne correspond pas au membre implémenté.
  • CS8616 - La nullabilité des types référence dans le type de retour ne correspond pas au membre implémenté.
  • CS8617 - La nullabilité des types référence dans le type de paramètre ne correspond pas au membre implémenté.
  • CS8618 - Une variable non nullable doit contenir une valeur non null au moment de la sortie du constructeur. Envisagez de la déclarer comme nullable.
  • CS8619 - La nullabilité des types référence dans la valeur ne correspond pas au type cible.
  • CS8620 - Impossible d’utiliser l’argument pour le paramètre, car il existe des différences dans la nullabilité des types référence.
  • CS8621 - La nullabilité des types référence dans le type de retour ne correspond pas au délégué cible (possiblement en raison des attributs de nullabilité).
  • CS8622 - La nullabilité des types référence dans le type de paramètre ne correspond pas au délégué cible (possiblement en raison des attributs de nullabilité).
  • CS8624 - Impossible d’utiliser l’argument comme sortie, car il existe des différences dans la nullabilité des types référence.
  • CS8625 - Impossible de convertir un littéral null en type référence non nullable.
  • CS8629 - Le type valeur nullable est peut-être null.
  • CS8631 - Impossible d’utiliser le type en tant que paramètre de type dans le type ou la méthode générique. La nullabilité de l’argument de type ne correspond pas au type de contrainte.
  • CS8633 - La nullabilité dans les contraintes pour le paramètre de type de la méthode ne correspond pas aux contraintes pour le paramètre de type de la méthode d’interface. Utilisez à la place une implémentation d’interface explicite.
  • CS8634 - Impossible d’utiliser le type en tant que paramètre de type dans le type ou la méthode générique. La nullabilité de l’argument de type ne correspond pas à la contrainte « class ».
  • CS8643 - La nullabilité des types référence dans le spécificateur d’interface explicite ne correspond pas à l’interface implémentée par le type.
  • CS8644 - Le type n’implémente pas le membre d’interface. La nullabilité des types référence dans l’interface implémentée par le type de base ne correspond pas.
  • CS8645 - Le membre figure déjà dans la liste des interfaces sur le type avec une nullabilité différente des types référence.
  • CS8655 - L’expression switch ne prend pas en charge certaines entrées null (elle n’est pas exhaustive).
  • CS8667 - Les déclarations de méthodes partielles ont une nullabilité incohérente dans les contraintes pour le paramètre de type.
  • CS8670 - L’initialiseur d’objet ou de collection déréférence implicitement le membre possiblement null.
  • CS8714 - Impossible d’utiliser le type en tant que paramètre de type dans le type ou la méthode générique. La nullabilité de l’argument de type ne correspond pas à la contrainte « notnull ».
  • CS8762 - Le paramètre doit avoir une valeur non null au moment de la sortie.
  • CS8763 - Une méthode marquée [DoesNotReturn] ne doit pas retourner.
  • CS8764 - La nullabilité du type de retour ne correspond pas au membre surchargé (possiblement en raison des attributs de nullabilité).
  • CS8765 - La nullabilité de type du paramètre ne correspond pas au membre surchargé (possiblement en raison des attributs de nullabilité).
  • CS8766 - La nullabilité des types référence dans le type de retour ne correspond pas au membre implémenté implicitement (possiblement en raison des attributs de nullabilité).
  • CS8767 - La nullabilité des types référence dans le type de retour ne correspond pas au membre implémenté implicitement (possiblement en raison des attributs de nullabilité).
  • CS8768 - La nullabilité des types référence dans le type de retour ne correspond pas au membre implémenté (possiblement en raison des attributs de nullabilité).
  • CS8769 - La nullabilité des types référence dans le type de paramètre ne correspond pas au membre implémenté (possiblement en raison des attributs de nullabilité).
  • CS8770 - La méthode n’a pas d’annotation [DoesNotReturn] correspondant au membre implémenté ou surchargé.
  • CS8774 - Le paramètre doit avoir une valeur non null au moment de la sortie.
  • CS8776 - Le membre ne peut pas être utilisé dans cet attribut.
  • CS8775 - Le paramètre doit avoir une valeur non null au moment de la sortie.
  • CS8777 - Le paramètre doit avoir une valeur non null au moment de la sortie.
  • CS8819 - La nullabilité des types référence dans le type de retour ne correspond pas à la déclaration de méthode partielle.
  • CS8824 - Le paramètre doit avoir une valeur non null au moment de la sortie, car le paramètre a une valeur non null.
  • CS8825 - La valeur de retour doit être non null, car le paramètre est non null.
  • CS8847 - L’expression switch ne gère pas certaines entrées null (elle n’est pas exhaustive). Cependant, un modèle avec une clause « when » pourrait établit une correspondance avec cette valeur.

L’objectif des avertissements « nullables » est de réduire les risques que votre application lève une System.NullReferenceException lors de l’exécution. Pour atteindre cet objectif, le compilateur utilise l’analyse statique et émet des avertissements lorsque votre code a des constructions qui peuvent entraîner des exceptions de référence null. Vous fournissez au compilateur des informations pour son analyse statique en appliquant des attributs et des annotations de type. Ces annotations et attributs décrivent la nullabilité des arguments, paramètres et membres de vos types. Dans cet article, vous allez découvrir différentes techniques pour corriger les avertissements nullables que le compilateur génère à partir de son analyse statique. Les techniques décrites ici concernent le code C# général. Découvrez comment utiliser les types référence nullables et Entity Framework Core dans Utilisation des types référence nullables.

Vous résoudrez presque tous les avertissements à l’aide de l’une des quatre techniques suivantes :

  • Ajout de contrôles de valeur null nécessaires.
  • Ajout d’annotations nullables ? ou !.
  • Ajout d’attributs qui décrivent la sémantique null.
  • Initialisation correcte des variables.

Déréférencement possible de null

Cet ensemble d’avertissements vous alerte du fait que vous déréférencez une variable dont l’état de nullabilité (null-state) est peut-être null (maybe-null). Ces avertissements sont les suivants :

  • CS8602 - Déréférencement d’une référence possiblement null.
  • CS8670 - L’initialiseur d’objet ou de collection déréférence implicitement le membre possiblement null.

Le code suivant montre un exemple de chacun des avertissements précédents :

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
}

Dans l’exemple ci-dessus, l’avertissement est dû au fait que le Container, c, peut avoir une valeur null pour la propriété States. L’affectation de nouveaux états à une collection qui peut être null provoque l’avertissement.

Pour supprimer ces avertissements, vous devez ajouter du code pour changer le null-state de cette variable en not-null avant de la déréférencer. L’avertissement de l’initialiseur de collection peut être plus difficile à repérer. Le compilateur détecte que la collection peut être null quand l’initialiseur y ajoute des éléments.

Dans de nombreux cas, vous pouvez corriger ces avertissements en vérifiant qu’une variable n’est pas null avant de la déréférencer. Tenez compte du code suivant qui ajoute un contrôle de valeur null avant de déréférencer le paramètre message :

void WriteMessageLength(string? message)
{
    if (message is not null)
    {
        Console.WriteLine(message.Length);
    }
    
}

L’exemple suivant initialise le stockage externe pour States et supprime l’accesseur set. Les consommateurs de la classe peuvent modifier le contenu de la collection, et le stockage de la collection n’est jamais null :

class Container
{
    public List<string> States { get; } = new();
}

D’autres cas où vous recevez ces avertissements peuvent être faux positifs. Vous pouvez avoir une méthode d’utilitaire privée qui teste la valeur null. Le compilateur ne sait pas que la méthode fournit un contrôle de valeur null. Prenons l’exemple suivant qui utilise une méthode d’utilitaire privée, IsNotNull :

public void WriteMessage(string? message)
{
    if (IsNotNull(message))
        Console.WriteLine(message.Length);
}

Le compilateur avertit que vous pouvez déréférencer la valeur null lorsque vous écrivez la propriété message.Length, car son analyse statique détermine que message peut être null. Vous savez peut-être que IsNotNull fournit un contrôle de valeur null et quand celui-ci retourne true, le null-state de message doit être not-null. Vous devez indiquer ces faits au compilateur. Un moyen consiste à utiliser l’opérateur null forgiving, !. Vous pouvez changer l’instruction WriteLine pour la faire correspondre au code suivant :

Console.WriteLine(message!.Length);

L’opérateur null forgiving rend l’expression not-null même si elle était maybe-null sans le ! appliqué. Dans cet exemple, une meilleure solution consiste à ajouter un attribut à la signature de IsNotNull :

private static bool IsNotNull([NotNullWhen(true)] object? obj) => obj != null;

System.Diagnostics.CodeAnalysis.NotNullWhenAttribute informe le compilateur que l’argument utilisé pour le paramètre obj est not-null lorsque la méthode retourne true. Lorsque la méthode retourne false, l’argument a le même null-state qu’il avait avant l’appel de la méthode.

Conseil

Vous pouvez utiliser un ensemble complet d’attributs pour décrire la façon dont vos méthodes et propriétés affectent null-state. Vous les trouverez dans l’article de référence sur le langage, Attributs d’analyse statique nullables.

La correction d’un avertissement pour le déréférencement d’une variable maybe-null implique l’une des trois techniques suivantes :

  • Ajouter un contrôle de valeur null manquant.
  • Ajouter des attributs d’analyse null sur les API pour affecter l’analyse statique du null-state du compilateur. Ces attributs informent le compilateur lorsqu’une valeur de retour ou un argument doit être maybe-null ou not-null après l’appel de la méthode.
  • Appliquer l’opérateur null forgiving ! à l’expression pour forcer l’état à être not-null.

Valeur null possible attribuée à une référence non nullable

Cet ensemble d’avertissements vous alerte du fait que vous affectez une variable dont le type est non nullable à une expression dont l’état de nullabilité est peut-être null. Ces avertissements sont les suivants :

  • CS8597 - La valeur levée est peut-être null.
  • CS8600 - Conversion de littéral ayant une valeur null ou d’une éventuelle valeur null en type non nullable.
  • CS8601 - Possible affectation d’une référence null.
  • CS8603 - Retour d’une possible référence null
  • CS8604 - Possible argument de référence null pour le paramètre.
  • CS8605 - Conversion unboxing d’une valeur possiblement null.
  • CS8625 - Impossible de convertir un littéral null en type référence non nullable.
  • CS8629 - Le type valeur nullable est peut-être null.

Le compilateur émet ces avertissements lorsque vous tentez d’affecter une expression qui est maybe-null à une variable qui est non nullable. Par exemple :

string? TryGetMessage(int id) => "";

string msg = TryGetMessage(42);  // Possible null assignment.

Les différents avertissements fournissent des détails sur le code, comme l’affectation, l’affectation de conversion unboxing, les instructions de retour, les arguments des méthodes et les expressions throw.

Vous pouvez effectuer l’une des trois actions pour résoudre ces avertissements. L’une consiste à ajouter l’annotation ? pour faire de la variable un type référence nullable. Ce changement peut entraîner d’autres avertissements. Le changement d’une variable en remplaçant une référence non nullable par une référence nullable change son null-state par défaut, qui passe de not-null à maybe-null. L’analyse statique du compilateur peut trouver des instances où vous déréférencez une variable qui est maybe-null.

Les autres actions indiquent au compilateur que le côté droit de l’affectation est not-null. L’expression à droite peut faire l’objet d’un contrôle de valeur null avant l’affectation, comme illustré dans l’exemple suivant :

string notNullMsg = TryGetMessage(42) ?? "Unknown message id: 42";

Les exemples précédents illustrent l’affectation de la valeur de retour d’une méthode. Vous pouvez annoter la méthode (ou la propriété) pour indiquer quand une méthode retourne une valeur not-null. System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute spécifie souvent qu’une valeur de retour est not-null lorsqu’un argument d’entrée est not-null. Une autre alternative consiste à ajouter l’opérateur null forgiving, !, à droite :

string msg = TryGetMessage(42)!;

La résolution d’un avertissement pour l’affectation d’une expression not-null à une variable not-null implique l’une des quatre techniques suivantes :

  • Remplacer le côté gauche de l’affectation par un type nullable. Cette action peut introduire de nouveaux avertissements lorsque vous déréférencez cette variable.
  • Fournir un contrôle de valeur null avant l’affectation.
  • Annoter l’API qui produit le côté droit de l’affectation.
  • Ajouter l’opérateur null forgiving à droite de l’affectation.

Référence non nullable non initialisée

Cet ensemble d’avertissements vous alerte du fait que vous affectez une variable dont le type est non nullable à une expression dont l’état de nullabilité est peut-être null. Ces avertissements sont les suivants :

  • CS8618 - Une variable non nullable doit contenir une valeur non null au moment de la sortie du constructeur. Envisagez de la déclarer comme nullable.
  • CS8762 - Le paramètre doit avoir une valeur non null au moment de la sortie.

Prenons la classe suivante comme exemple :

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Ni FirstName ni LastName ne sont garantis initialisés. Si ce code est nouveau, envisagez de changer l’interface publique. L’exemple ci-dessus pourrait être mis à jour comme ceci :

public class Person
{
    public Person(string first, string last)
    {
        FirstName = first;
        LastName = last;
    }

    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Si vous devez créer un objet Person avant de définir le nom, vous pouvez initialiser les propriétés à l’aide d’une valeur par défaut non null :

public class Person
{
    public string FirstName { get; set; } = string.Empty;
    public string LastName { get; set; } = string.Empty;
}

Une autre alternative consiste à remplacer ces membres par des types référence nullables. La classe Person pourrait être définie comme suit si null devait être autorisé pour le nom :

public class Person
{
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
}

Le code existant peut demander d’autres changements pour informer le compilateur de la sémantique null pour ces membres. Vous avez peut-être créé plusieurs constructeurs et votre classe peut avoir une méthode d’assistance privée qui initialise un ou plusieurs membres. Vous pouvez déplacer le code d’initialisation dans un seul constructeur et vous assurer que tous les constructeurs appellent celui avec le code d’initialisation commun. Vous pouvez également utiliser les attributs System.Diagnostics.CodeAnalysis.MemberNotNullAttribute et System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute. Ces attributs informent le compilateur qu’un membre est not-null une fois que la méthode a été appelée. Le code suivant montre un exemple de chaque. La classe Person utilise un constructeur commun appelé par tous les autres constructeurs. La classe Student a une méthode d’assistance annotée avec l’attribut System.Diagnostics.CodeAnalysis.MemberNotNullAttribute :


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";
    }
}

Enfin, vous pouvez utiliser l’opérateur null forgiving pour indiquer qu’un membre est initialisé dans un autre code. Pour avoir un autre exemple, prenons les classes suivantes représentant un modèle Entity Framework Core :

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!;
}

La propriété DbSet est initialisée à null!. Cela indique au compilateur que la propriété est définie sur une valeur not-null. En fait, le DbContext de base effectue l’initialisation de la définition. L’analyse statique du compilateur ne s’en occupe pas. Pour plus d’informations sur l’utilisation des types référence nullables et d’Entity Framework Core, consultez l’article Utilisation des types référence nullables dans EF Core.

La résolution d’un avertissement pour ne pas initialiser un membre non nullable implique l’une des quatre techniques suivantes :

  • Changer les constructeurs ou les initialiseurs de champ pour vous assurer que tous les membres non nullables sont initialisés.
  • Changer un ou plusieurs membres pour qu’ils soient des types nullables.
  • Annoter toutes les méthodes d’assistance pour indiquer quels membres sont affectés.
  • Ajouter un initialiseur à null! pour indiquer que le membre est initialisé dans un autre code.

Incompatibilité dans une déclaration de nullabilité

D’autres avertissements indiquent des non-correspondances de nullabilité entre les signatures pour les méthodes, les délégués ou les paramètres de type.

  • CS8608 - La nullabilité des types référence dans le type ne correspond pas au membre surchargé.
  • CS8609 - La nullabilité des types référence dans le type de retour ne correspond pas au membre surchargé.
  • CS8610 - La nullabilité des types référence dans le type de paramètre ne correspond pas au membre surchargé.
  • CS8611 - La nullabilité des types référence dans le type de paramètre ne correspond pas à la déclaration de méthode partielle.
  • CS8612 - La nullabilité des types référence dans le type ne correspond pas au membre implémenté implicitement.
  • CS8613 - La nullabilité des types référence dans le type de retour ne correspond pas au membre implémenté implicitement.
  • CS8614 - La nullabilité des types référence dans le type de paramètre ne correspond pas au membre implémenté implicitement.
  • CS8615 - La nullabilité des types référence dans le type ne correspond pas au membre implémenté.
  • CS8616 - La nullabilité des types référence dans le type de retour ne correspond pas au membre implémenté.
  • CS8617 - La nullabilité des types référence dans le type de paramètre ne correspond pas au membre implémenté.
  • CS8619 - La nullabilité des types référence dans la valeur ne correspond pas au type cible.
  • CS8620 - Impossible d’utiliser l’argument pour le paramètre, car il existe des différences dans la nullabilité des types référence.
  • CS8621 - La nullabilité des types référence dans le type de retour ne correspond pas au délégué cible (possiblement en raison des attributs de nullabilité).
  • CS8622 - La nullabilité des types référence dans le type de paramètre ne correspond pas au délégué cible (possiblement en raison des attributs de nullabilité).
  • CS8624 - Impossible d’utiliser l’argument comme sortie, car il existe des différences dans la nullabilité des types référence.
  • CS8631 - Impossible d’utiliser le type en tant que paramètre de type dans le type ou la méthode générique. La nullabilité de l’argument de type ne correspond pas au type de contrainte.
  • CS8633 - La nullabilité dans les contraintes pour le paramètre de type de la méthode ne correspond pas aux contraintes pour le paramètre de type de la méthode d’interface. Utilisez à la place une implémentation d’interface explicite.
  • CS8634 - Impossible d’utiliser le type en tant que paramètre de type dans le type ou la méthode générique. La nullabilité de l’argument de type ne correspond pas à la contrainte « class ».
  • CS8643 - La nullabilité des types référence dans le spécificateur d’interface explicite ne correspond pas à l’interface implémentée par le type.
  • CS8644 - Le type n’implémente pas le membre d’interface. La nullabilité des types référence dans l’interface implémentée par le type de base ne correspond pas.
  • CS8645 - Le membre figure déjà dans la liste des interfaces sur le type avec une nullabilité différente des types référence.
  • CS8667 - Les déclarations de méthodes partielles ont une nullabilité incohérente dans les contraintes pour le paramètre de type.
  • CS8714 - Impossible d’utiliser le type en tant que paramètre de type dans le type ou la méthode générique. La nullabilité de l’argument de type ne correspond pas à la contrainte « notnull ».
  • CS8764 - La nullabilité du type de retour ne correspond pas au membre surchargé (possiblement en raison des attributs de nullabilité).
  • CS8765 - La nullabilité de type du paramètre ne correspond pas au membre surchargé (possiblement en raison des attributs de nullabilité).
  • CS8766 - La nullabilité des types référence dans le type de retour ne correspond pas au membre implémenté implicitement (possiblement en raison des attributs de nullabilité).
  • CS8767 - La nullabilité des types référence dans le type de retour ne correspond pas au membre implémenté implicitement (possiblement en raison des attributs de nullabilité).
  • CS8768 - La nullabilité des types référence dans le type de retour ne correspond pas au membre implémenté (possiblement en raison des attributs de nullabilité).
  • CS8769 - La nullabilité des types référence dans le type de paramètre ne correspond pas au membre implémenté (possiblement en raison des attributs de nullabilité).
  • CS8819 - La nullabilité des types référence dans le type de retour ne correspond pas à la déclaration de méthode partielle.

Le code suivant illustre CS8764 :

public class B
{
    public virtual string GetMessage(string id) => string.Empty;
}
public class D : B
{
    public override string? GetMessage(string? id) => default;
}

L’exemple précédent montre une méthode virtual dans une classe de base et un override avec une nullabilité différente. La classe de base retourne une chaîne non nullable, mais la classe dérivée retourne une chaîne nullable. Si string et string? étaient inversés, cela serait autorisé parce que la classe dérivée est plus restrictive. De même, les déclarations de paramètres doivent correspondre. Les paramètres de la méthode override peuvent autoriser la valeur null même si la classe de base ne l’autorise pas.

D’autres situations peuvent générer ces avertissements. Vous pouvez avoir une incompatibilité dans une déclaration de méthode d’interface et l’implémentation de cette méthode. Ou un type de délégué et l’expression de ce délégué peuvent différer. Un paramètre de type et l’argument de type peuvent différer dans la nullabilité.

Pour corriger ces avertissements, mettez à jour la déclaration appropriée.

Le code ne correspond pas à la déclaration d’attribut

Les sections précédentes ont expliqué comment utiliser les attributs pour une analyse statique nullable afin d’informer le compilateur de la sémantique null de votre code. Le compilateur vous avertit si le code ne respecte pas les promesses de cet attribut.

  • CS8607 - Une possible valeur null ne peut pas être utilisée pour un type marqué avec [NotNull] ou [DisallowNull]
  • CS8763 - Une méthode marquée [DoesNotReturn] ne doit pas retourner.
  • CS8770 - La méthode n’a pas d’annotation [DoesNotReturn] correspondant au membre implémenté ou surchargé.
  • CS8774 - Le paramètre doit avoir une valeur non null au moment de la sortie.
  • CS8775 - Le paramètre doit avoir une valeur non null au moment de la sortie.
  • CS8776 - Le membre ne peut pas être utilisé dans cet attribut.
  • CS8777 - Le paramètre doit avoir une valeur non null au moment de la sortie.
  • CS8824 - Le paramètre doit avoir une valeur non null au moment de la sortie, car le paramètre a une valeur non null.
  • CS8825 - La valeur de retour doit être non null, car le paramètre est non null.

Considérez la méthode suivante :

public bool TryGetMessage(int id, [NotNullWhen(true)] out string? message)
{
    message = null;
    return true;

}

Le compilateur génère un avertissement parce que le paramètre message est nullet la méthode retourne true. L’attribut NotNullWhen indique que cela ne devrait pas se produire.

Pour corriger ces avertissements, mettez à jour votre code afin qu’il corresponde aux attentes des attributs que vous avez appliqués. Vous pouvez changer les attributs ou l’algorithme.

Expression switch exhaustive

Les expressions switch doivent être exhaustives, ce qui signifie que toutes les valeurs d’entrée doivent être gérées. Même pour les types référence non nullables, la valeur null doit être prise en compte. Le compilateur émet des avertissements quand la valeur null n’est pas gérée :

  • CS8655 - L’expression switch ne prend pas en charge certaines entrées null (elle n’est pas exhaustive).
  • CS8847 - L’expression switch ne gère pas certaines entrées null (elle n’est pas exhaustive). Cependant, un modèle avec une clause « when » pourrait établit une correspondance avec cette valeur.

L’exemple de code suivant illustre cette condition :

int AsScale(string status) =>
    status switch
    {
        "Red" => 0,
        "Yellow" => 5,
        "Green" => 10,
        { } => -1
    };

L’expression d’entrée est un string, et non pas un string?. Le compilateur génère néanmoins cet avertissement. Le modèle { } gère toutes les valeurs non null, mais pas null. Pour traiter ces erreurs, vous pouvez ajouter un cas null explicite ou remplacer le { } par le modèle (discard) _. Le modèle discard traite les cas des valeurs null ainsi que de n’importe quelle autre valeur.