Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
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 comporte des constructions susceptibles d'entraîner des exceptions de référence nulle. 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 apprendre différentes techniques pour traiter les avertissements nullables générés par le compilateur à 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.
Les types de référence nullables, y compris les opérateurs ?
et les !
sont autorisés uniquement lorsque le contexte nullable est défini sur enable
ou annotations
. Vous pouvez définir le contexte nullable à l’aide de l’option de compilateur Nullable
dans votre fichier projet ou à l’aide du pragma #nullable
dans votre code source.
Cet article traite des avertissements suivantes du compilateur :
- CS8597 - La valeur rejetée peut être nulle.
- CS8598 - L’opérateur de suppression n’est pas autorisé dans ce contexte
- CS8600 - Conversion d'un littéral null ou d'une valeur null possible en un 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 possible d’une référence nulle.
- CS8604 - Possible argument de référence null pour le paramètre.
- CS8605 - Déballage d'une valeur éventuellement nulle.
- CS8607 - Une possible valeur null ne peut pas être utilisée pour un type marqué avec
[NotNull]
ou[DisallowNull]
- CS8608 - La nullabilité des types de référence dans le type ne correspond pas à un membre surchargé.
- CS8609 - La nullabilité des types de référence dans le type de retour ne correspond pas à celle des membres surchargés.
- CS8610 - La nullabilité des types de référence dans le paramètre de type ne correspond pas à celle des membres surchargés.
- CS8611 - La nullabilité des types référence du paramètre de type ne correspond pas à la déclaration de méthode partielle.
- CS8612 - La nullabilité des types de référence dans le type ne correspond pas à un membre implémenté implicitement.
- CS8613 - La nullabilité des types de référence dans le type de retour ne correspond pas au membre implicitement implémenté.
- CS8614 - La nullabilité des types de référence ne correspond pas dans le type de paramètre au membre implémenté implicitement.
- CS8615 - La nullabilité des types de référence dans le type ne correspond pas au membre implémenté.
- CS8616 - La nullabilité des types de référence dans le type de retour ne correspond pas au membre implémenté.
- CS8617 - La nullabilité des types de 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 une valeur ne correspond pas au type de destination.
- 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 de référence dans le type de retour ne correspond pas au délégué cible (peut-être à cause des attributs de nullabilité).
- CS8622 - La nullabilité des types de référence dans le type de paramètre ne correspond pas au délégué cible (peut-être à cause des attributs de nullabilité).
- CS8623 - 'application explicite de
System.Runtime.CompilerServices.NullableAttribute
n’est pas autorisée. - 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.
- CS8628 - Impossible d’utiliser un type de référence nullable dans la création d’objets.
- 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.
- CS8632 - L’annotation pour les types de référence nullables ne doit être utilisée que dans le code dans un contexte d’annotations
#nullable
. - 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 ».
- CS8636 - Option non valide pour
/nullable
; doit êtredisable
,enable
,warnings
ouannotations
- CS8637 - Attendu :
enable
,disable
, oorestore
- CS8639 - L’opérateur typeof ne peut pas être utilisé sur un type de référence nullable
- 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 de l'interface. La nullabilité des types de 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 les types dont la nullabilité est différente de celle des types de 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 à celle du membre remplacé (peut-être à cause des attributs de nullabilité).
- CS8765 - La nullabilité du type de paramètre ne correspond pas à celle du membre remplacé (peut-être à cause des attributs de nullité).
- CS8766 - La nullabilité des types de référence dans le type de retour de ne correspond pas au membre implémenté implicitement (peut-être à cause des attributs de nullabilité).
- CS8767 - La nullabilité des types de référence dans le type du paramètre de ne correspond pas au membre implémenté implicitement (peut-être à cause des attributs de nullabilité).
- CS8768 - La nullabilité des types de référence dans le type de retour ne correspond pas au membre implémenté (peut-être à cause des attributs de nullabilité).
- CS8769 - La nullabilité des types de référence dans le type de paramètre ne correspond pas au membre implémenté (peut-être à cause des attributs de nullabilité).
- CS8770 - Il manque à la méthode l'annotation
[DoesNotReturn]
pour correspondre au membre implémenté ou surchargé. - CS8774 - Le paramètre doit avoir une valeur non null au moment de la sortie.
- CS8776 - Ce 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 de 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.
Note
L’analyse statique ne peut pas toujours déduire dans quel ordre, dans un scénario spécifique, les méthodes sont accessibles et si la méthode se termine correctement sans lever d’exception. Ces pièges connus sont bien décrits dans la section Pièges connus.
Vous traitez presque tous les avertissements à l’aide de l’une des cinq techniques suivantes :
- Configuration du contexte nullable.
- Ajout de contrôles de valeur null nécessaires.
- Ajout ou suppression d'annotations
?
ou!
nullables. - Ajout d’attributs qui décrivent la sémantique null.
- Initialisation correcte des variables.
Si vous n'avez pas l'habitude d'utiliser les types de référence nullables, la vue d'ensemble des types de référence nullables fournit un aperçu de ce que les types de référence nullables permettent de résoudre et de la manière dont ils fonctionnent pour avertir des erreurs possibles dans votre code. Vous pouvez également consulter les instructions sur la migration de vers des types de référence nullables pour en savoir plus sur l’activation des types de référence nullables dans un projet existant.
Configuration du contexte nullable
Les avertissements suivants indiquent que vous n’avez pas correctement défini le contexte nullable :
- CS8632 - L’annotation pour les types de référence nullables ne doit être utilisée que dans le code dans un contexte d’annotations
#nullable
. - CS8636 - option Non valide pour
/nullable
; doit êtredisable
,enable
,warnings
ouannotations
- CS8637 - Attendu:
enable
,disable
, ourestore
Syntaxe d’annotation incorrecte
Ces erreurs et avertissements indiquent que l’utilisation de l’annotation !
ou ?
est incorrecte.
- CS8598 - L’opérateur de suppression n’est pas autorisé dans ce contexte
- CS8623 - L'application explicite de
System.Runtime.CompilerServices.NullableAttribute
n’est pas autorisée. - CS8628 - Impossible d’utiliser un type de référence nullable dans la création d’objets.
- CS8639 - L’opérateur typeof ne peut pas être utilisé sur un type de référence nullable
L’annotation ?
dans une déclaration indique que la variable peut être null. Il n’indique pas de type d’exécution différent. Les deux déclarations suivantes sont le même type d’exécution :
string s1 = "a string";
string? s2 = "another string";
L'?
est un indicateur pour le compilateur sur l’attente de valeurs Null.
L’annotation !
sur une expression indique que vous savez que l’expression est sécurisée et qu’elle doit être supposée ne pas avoir la valeur Null.
- Vous devez utiliser ces annotations, et non les System.Runtime.CompilerServices.NullableAttribute dans votre code.
- Étant donné que le
?
est une annotation, et non un type, vous ne pouvez pas l’utiliser avectypeof
, ounew
expressions. - L’opérateur
!
ne peut pas être appliqué à une expression variable ou à un groupe de méthodes. - L’opérateur
!
ne peut pas être appliqué à gauche d’un opérateur d’accès membre, tel queobj.Field!.Method()
.
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 précédent, 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 relatif à l'initialisateur 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. Prenons l’exemple suivant qui ajoute une vérification null avant de déreferencer 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();
}
Dans d'autres cas, ces avertissements peuvent être des faux positifs. Vous pouvez avoir une méthode d’utilitaire privé 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 vous avertit que vous risquez de déréférencer null lorsque vous écrivez la propriété message.Length
, car son analyse statique détermine que message
pourrait être null
. Vous savez que IsNotNull
fournit une vérification de nullité et que lorsqu'il renvoie true
, l'état de nullité 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 de nullité sur les API afin d'influencer l'analyse statique de l'état null 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 qui force l'état à 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 rejetée peut être nulle.
- CS8600 - Conversion d'un littéral null ou d'une valeur potentiellement null en type non nullable.
- CS8601 - Possible affectation d’une référence null.
- CS8603 - Retour possible d'une référence nulle.
- CS8604 - Possible argument de référence null pour le paramètre.
- CS8605 - Déballage d'une valeur éventuellement nulle.
- CS8625 - Impossible de convertir un littéral null en type de référence non nulle.
- 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. Cette modification 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 recherche des instances où vous déréférez une variable peut-être 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 annotez la méthode (ou la propriété) pour indiquer quand une méthode retourne une valeur non 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 peut-être-nulle à une variable non nulle 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éférez 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 précédent peut être mis à jour comme suit :
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 de 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 nécessite parfois d’autres modifications pour informer le compilateur de la sémantique Null de ces membres. Il peut avoir plusieurs constructeurs, et votre classe a 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 après le retour de la méthode. 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, la base DbContext
effectue l'initialisation de l'ensemble. 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 non-initialisation d’un membre non nullable implique l’une des quatre options suivantes :
- Changer les constructeurs ou les initialiseurs de champ pour s'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.
Inadéquation dans la 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 de référence dans le type ne correspond pas à celle des membres surchargés.
- CS8609 - La nullabilité des types de référence dans le type de retour ne correspond pas à celle des membres surchargés.
- CS8610 - La nullabilité des types de référence dans le paramètre de type ne correspond pas à celle des membres surchargés.
- 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 de référence au sein du type ne correspond pas au membre implémenté implicitement.
- CS8613 - La nullabilité des types de référence dans le type de retour ne correspond pas à celle du membre mis en œuvre 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 de référence dans le type ne correspond pas au membre implémenté.
- CS8616 - La nullabilité des types de référence dans le type de retour ne correspond pas au membre implémenté.
- CS8617 - La nullabilité des types de référence dans le type du paramètre ne correspond pas à celle du membre implémenté.
- CS8619 - La nullabilité des types de 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 de référence dans le type de retour ne correspond pas au délégué cible (peut-être à cause des attributs de nullabilité).
- CS8622 - La nullabilité des types de référence dans le type de paramètre ne correspond pas au délégué cible (peut-être à cause 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 de l'interface. La nullabilité des types de 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 les types dont la nullabilité est différente de celle des types de 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 à celle du membre remplacé (peut-être à cause des attributs de nullabilité).
- CS8765 - La nullabilité du type de paramètre ne correspond pas à celle du membre remplacé (peut-être à cause des attributs de nullité).
- CS8766 - La nullabilité des types de référence dans le type de retour de ne correspond pas au membre implémenté implicitement (peut-être à cause des attributs de nullabilité).
- CS8767 - La nullabilité des types de référence dans le type du paramètre de ne correspond pas au membre implémenté implicitement (peut-être à cause des attributs de nullabilité).
- CS8768 - La nullabilité des types de référence dans le type de retour ne correspond pas au membre implémenté (peut-être à cause des attributs de nullabilité).
- CS8769 - La nullabilité des types de référence dans le type de paramètre ne correspond pas au membre implémenté (peut-être 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 avez 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 pour ce délégué diffèrent. Un paramètre de type et l’argument de type diffèrent en 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 expliquent comment utiliser Attributs pour l’analyse statique nullable pour informer le compilateur sur 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 - Il manque à la méthode l'annotation
[DoesNotReturn]
pour correspondre 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
a la valeur null
et la méthode retourne true
. L’attribut NotNullWhen
indique que cela ne devrait pas se produire.
Pour résoudre ces avertissements, mettez à jour votre code afin qu’il corresponde aux attentes des attributs appliqués. Vous pouvez modifier 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 de correspondance correspond à null en plus de toute autre valeur.