Types références NullablesNullable reference types

C# 8.0 introduit des types référence nullables et des types référence non nullables qui vous permettent d’établir des instructions importantes sur les propriétés de variables de type référence :C# 8.0 introduces nullable reference types and non-nullable reference types that enable you to make important statements about the properties for reference type variables:

  • Une référence ne doit pas être null.A reference isn't supposed to be null. Lorsque les variables ne sont pas censées être null, le compilateur applique des règles qui garantissent que le déréférencement de ces variables est sécurisé sans avoir d’abord vérifié qu’elle n’est pas NULL :When variables aren't supposed to be null, the compiler enforces rules that ensure it's safe to dereference these variables without first checking that it isn't null:
    • La variable doit être initialisée avec une valeur non null.The variable must be initialized to a non-null value.
    • La variable ne peut jamais se voir attribuer la valeur null.The variable can never be assigned the value null.
  • Une référence peut être null.A reference may be null. Lorsque les variables peuvent être null, le compilateur applique des règles différentes pour garantir que vous avez correctement vérifié une référence null :When variables may be null, the compiler enforces different rules to ensure that you've correctly checked for a null reference:
    • La variable peut être déréférencée seulement si le compilateur peut garantir que la valeur n’est pas null.The variable may only be dereferenced when the compiler can guarantee that the value isn't null.
    • Ces variables peuvent être initialisées avec la valeur null par défaut et peuvent se voir attribuer la valeur null dans un autre code.These variables may be initialized with the default null value and may be assigned the value null in other code.

Cette nouvelle fonctionnalité offre des avantages significatifs par rapport à la gestion des variables de référence dans les versions antérieures de C#, où l’intention de conception ne peut pas être déterminée à partir de la déclaration de la variable.This new feature provides significant benefits over the handling of reference variables in earlier versions of C# where the design intent can't be determined from the variable declaration. Le compilateur ne protégeait pas des exceptions de référence null pour les types référence :The compiler didn't provide safety against null reference exceptions for reference types:

  • Une référence peut être null.A reference can be null. Le compilateur n’émet pas d’avertissements quand une variable de type référence est initialisée à null ou ultérieurement assignée null .The compiler doesn't issue warnings when a reference-type variable is initialized to null, or later assigned null. Le compilateur émet des avertissements lorsque ces variables sont déréférencées sans contrôles null.The compiler issues warnings when these variables are dereferenced without null checks.
  • Une référence est censée ne pas être null.A reference is assumed to be not null. Le compilateur ne génère aucun avertissement quand les types référence sont déréférencés.The compiler doesn't issue any warnings when reference types are dereferenced. Le compilateur émet des avertissements si une variable est définie sur une expression qui peut être null.The compiler issues warnings if a variable is set to an expression that may be null.

Ces avertissements sont émis au moment de la compilation.These warnings are emitted at compile time. Le compilateur n’ajoute pas de contrôles null ou autres constructions d’exécution dans un contexte Nullable.The compiler doesn't add any null checks or other runtime constructs in a nullable context. Au moment de l’exécution, une référence Nullable et une référence non Nullable sont équivalentes.At runtime, a nullable reference and a non-nullable reference are equivalent.

En ajoutant des types référence nullables, vous pouvez déclarer votre intention plus clairement.With the addition of nullable reference types, you can declare your intent more clearly. La valeur null est un bon moyen de représenter qu’une variable ne fait pas référence à une valeur.The null value is the correct way to represent that a variable doesn't refer to a value. N’utilisez pas cette fonctionnalité pour supprimer toutes les valeurs null de votre code.Don't use this feature to remove all null values from your code. Déclarez plutôt votre intention au compilateur et aux autres développeurs qui lisent votre code.Rather, you should declare your intent to the compiler and other developers that read your code. Quand vous déclarez votre intention, le compilateur vous informe si vous écrivez du code qui n’est pas en phase avec cette intention.By declaring your intent, the compiler informs you when you write code that is inconsistent with that intent.

Un type de référence nullable est inidqué avec la même syntaxe que celle des types valeur nullable : un ? est ajouté au type de la variable.A nullable reference type is noted using the same syntax as nullable value types: a ? is appended to the type of the variable. Par exemple, la déclaration de variable suivante représente une variable de chaîne nullable, name :For example, the following variable declaration represents a nullable string variable, name:

string? name;

Toute variable où ? n’est pas ajouté au nom de type est un type de référence non Nullable.Any variable where the ? isn't appended to the type name is a non-nullable reference type. Cela comprend toutes les variables de type référence dans le code existant lorsque vous avez activé cette fonctionnalité.That includes all reference type variables in existing code when you've enabled this feature.

Le compilateur utilise l’analyse statique pour déterminer si une référence nullable est connue pour être non null.The compiler uses static analysis to determine if a nullable reference is known to be non-null. Le compilateur vous avertit si vous déréférencez une référence nullable quand elle est susceptible d’être null.The compiler warns you if you dereference a nullable reference when it may be null. Vous pouvez remplacer ce comportement à l’aide de l' opérateur null-indulgent avec à la ! suite d’un nom de variable.You can override this behavior by using the null-forgiving operator ! following a variable name. Par exemple, si vous savez que la variable name n’est pas null alors que le compilateur génère un avertissement, vous pouvez écrire le code suivant pour remplacer l’analyse du compilateur :For example, if you know the name variable isn't null but the compiler issues a warning, you can write the following code to override the compiler's analysis:

name!.Length;

Nullabilité des typesNullability of types

Tout type référence peut avoir l’une des quatre nullabilités, qui décrit quand des avertissements sont générés :Any reference type can have one of four nullabilities, which describes when warnings are generated:

  • Non null: aucune valeur NULL ne peut être assignée aux variables de ce type.Nonnullable: Null can't be assigned to variables of this type. Les variables de ce type n’ont pas besoin d’être vérifiées pour savoir si elles ont la valeur null avant d’être déréférencées.Variables of this type don't need to be null-checked before dereferencing.
  • Nullable: la valeur NULL peut être assignée aux variables de ce type.Nullable: Null can be assigned to variables of this type. Le déréférencement des variables de ce type sans vérifier null au préalable génère un avertissement.Dereferencing variables of this type without first checking for null causes a warning.
  • Oublie: oublie est l’état pré-C # 8,0.Oblivious: Oblivious is the pre-C# 8.0 state. Les variables de ce type peuvent être déréférencées ou attribuées sans avertissement.Variables of this type can be dereferenced or assigned without warnings.
  • Inconnu: inconnu est généralement utilisé pour les paramètres de type où les contraintes n’indiquent pas au compilateur que le type doit être Nullable ou ne peut pas être null.Unknown: Unknown is generally for type parameters where constraints don't tell the compiler that the type must be nullable or nonnullable.

La nullabilité d’un type dans une déclaration de variable est contrôlée par le contexte nullable dans lequel la variable est déclarée.The nullability of a type in a variable declaration is controlled by the nullable context in which the variable is declared.

Contextes nullablesNullable contexts

Les contextes nullables permettent de contrôler précisément comment le compilateur interprète les variables de type référence.Nullable contexts enable fine-grained control for how the compiler interprets reference type variables. Le contexte d’annotation Nullable d’une ligne source donnée est activé ou désactivé.The nullable annotation context of any given source line is either enabled or disabled. Vous pouvez considérer le compilateur pre-C # 8,0 comme en compilant tout votre code dans un contexte Nullable désactivé : tout type de référence peut être null.You can think of the pre-C# 8.0 compiler as compiling all your code in a disabled nullable context: any reference type may be null. Le contexte d’avertissements Nullable peut également être activé ou désactivé.The nullable warnings context may also be enabled or disabled. Le contexte d’avertissements nullable spécifie les avertissements générés par le compilateur à l’aide de son analyse de flux.The nullable warnings context specifies the warnings generated by the compiler using its flow analysis.

Le contexte d’annotation Nullable et le contexte d’avertissement Nullable peuvent être définis pour un projet à l’aide de l' Nullable élément dans votre fichier . csproj .The nullable annotation context and nullable warning context can be set for a project using the Nullable element in your .csproj file. Cet élément configure comment le compilateur interprète la nullabilité des types et quels avertissements sont générés.This element configures how the compiler interprets the nullability of types and what warnings are generated. Les paramètres valides sont :Valid settings are:

  • enable: Le contexte d’annotation Nullable est activé.enable: The nullable annotation context is enabled. Le contexte d’avertissement nullable est activé.The nullable warning context is enabled.
    • Les variables d’un type référence, string par exemple, sont non nullables.Variables of a reference type, string for example, are non-nullable. Tous les avertissements de nullabilité sont activés.All nullability warnings are enabled.
  • warnings: Le contexte d’annotation Nullable est désactivé.warnings: The nullable annotation context is disabled. Le contexte d’avertissement nullable est activé.The nullable warning context is enabled.
    • Les variables d’un type référence sont oblivious.Variables of a reference type are oblivious. Tous les avertissements de nullabilité sont activés.All nullability warnings are enabled.
  • annotations: Le contexte d’annotation Nullable est activé.annotations: The nullable annotation context is enabled. Le contexte d’avertissement nullable est désactivé.The nullable warning context is disabled.
    • Les variables d’un type référence, String par exemple, ne sont pas nullables.Variables of a reference type, string for example, are non-nullable. Tous les avertissements de nullabilité sont désactivés.All nullability warnings are disabled.
  • disable: Le contexte d’annotation Nullable est désactivé.disable: The nullable annotation context is disabled. Le contexte d’avertissement nullable est désactivé.The nullable warning context is disabled.
    • Les variables d’un type référence sont oblivious, comme dans les versions antérieures de C#.Variables of a reference type are oblivious, just like earlier versions of C#. Tous les avertissements de nullabilité sont désactivés.All nullability warnings are disabled.

Exemple :Example:

<Nullable>enable</Nullable>

Vous pouvez aussi utiliser des directives pour définir ces mêmes contextes partout dans votre projet :You can also use directives to set these same contexts anywhere in your project:

  • #nullable enable: Définit le contexte d’annotation Nullable et le contexte d’avertissement Nullable sur activé.#nullable enable: Sets the nullable annotation context and nullable warning context to enabled.
  • #nullable disable: Définit le contexte d’annotation Nullable et le contexte d’avertissement Nullable sur désactivé.#nullable disable: Sets the nullable annotation context and nullable warning context to disabled.
  • #nullable restore: Restaure le contexte d’annotation Nullable et le contexte d’avertissement Nullable aux paramètres du projet.#nullable restore: Restores the nullable annotation context and nullable warning context to the project settings.
  • #nullable disable warnings: Affectez la valeur désactivé au contexte d’avertissement Nullable.#nullable disable warnings: Set the nullable warning context to disabled.
  • #nullable enable warnings: Affectez la valeur activé au contexte d’avertissement Nullable.#nullable enable warnings: Set the nullable warning context to enabled.
  • #nullable restore warnings: Restaure le contexte d’avertissement Nullable aux paramètres du projet.#nullable restore warnings: Restores the nullable warning context to the project settings.
  • #nullable disable annotations: Affectez la valeur désactivé au contexte d’annotation Nullable.#nullable disable annotations: Set the nullable annotation context to disabled.
  • #nullable enable annotations: Affectez la valeur activé au contexte d’annotation Nullable.#nullable enable annotations: Set the nullable annotation context to enabled.
  • #nullable restore annotations: Restaure le contexte d’avertissement d’annotation aux paramètres du projet.#nullable restore annotations: Restores the annotation warning context to the project settings.

Important

Le contexte Nullable global ne s’applique pas aux fichiers de code générés.The global nullable context does not apply for generated code files. Dans l’une ou l’autre stratégie, le contexte Nullable est désactivé pour tout fichier source marqué comme généré.Under either strategy, the nullable context is disabled for any source file marked as generated. Cela signifie que toutes les API dans les fichiers générés ne sont pas annotées.This means any APIs in generated files are not annotated. Un fichier est marqué comme généré de quatre façons :There are four ways a file is marked as generated:

  1. Dans le fichier. editorconfig, spécifiez generated_code = true dans une section qui s’applique à ce fichier.In the .editorconfig, specify generated_code = true in a section that applies to that file.
  2. Placez <auto-generated> ou <auto-generated/> dans un commentaire en haut du fichier.Put <auto-generated> or <auto-generated/> in a comment at the top of the file. Il peut se trouver sur n’importe quelle ligne de ce commentaire, mais le bloc de commentaires doit être le premier élément du fichier.It can be on any line in that comment, but the comment block must be the first element in the file.
  3. Démarrer le nom de fichier avec TemporaryGeneratedFile_Start the file name with TemporaryGeneratedFile_
  4. Terminez le nom de fichier avec . Designer.cs, . generated.cs, . g.cs ou . g.i.cs.End the file name with .designer.cs, .generated.cs, .g.cs, or .g.i.cs.

Les générateurs peuvent s’abonner à l’aide de la #nullable directive de préprocesseur.Generators can opt-in using the #nullable preprocessor directive.

Par défaut, l’annotation Nullable et les contextes d’avertissement sont désactivés, y compris les nouveaux projets.By default, nullable annotation and warning contexts are disabled, including new projects. Cela signifie que votre code existant est compilé sans modification et sans générer de nouveaux avertissements.That means that your existing code compiles without changes and without generating any new warnings.

Ces options fournissent deux stratégies distinctes pour mettre à jour une base de code existante afin d’utiliser des types de référence Nullable.These options provide two distinct strategies to update an existing codebase to use nullable reference types.

Contexte d’annotation nullableNullable annotation context

Le compilateur utilise les règles suivantes dans un contexte d’annotation nullable désactivé :The compiler uses the following rules in a disabled nullable annotation context:

  • Vous ne pouvez pas déclarer de références nullables dans un contexte désactivé.You can't declare nullable references in a disabled context.
  • Une valeur NULL peut être assignée à toutes les variables de référence.All reference variables may be assigned a value of null.
  • Aucun avertissement n’est généré lorsqu’une variable d’un type référence est déréférencée.No warnings are generated when a variable of a reference type is dereferenced.
  • L’opérateur null-forgiving ne peut pas être utilisé dans un contexte désactivé.The null-forgiving operator may not be used in a disabled context.

Le comportement est le même que dans les versions précédentes de C#.The behavior is the same as previous versions of C#.

Le compilateur utilise les règles suivantes dans un contexte d’annotation nullable activé :The compiler uses the following rules in an enabled nullable annotation context:

  • Toute variable d’un type référence est une référence non nullable.Any variable of a reference type is a non-nullable reference.
  • Toute référence non nullable peut être déréférencée sans problème.Any non-nullable reference may be dereferenced safely.
  • Tout type référence nullable (indiqué par ? après le type dans la déclaration de variable) peut être null.Any nullable reference type (noted by ? after the type in the variable declaration) may be null. L’analyse statique détermine si la valeur est connue pour être non null lorsqu’elle est déréférencée.Static analysis determines if the value is known to be non-null when it's dereferenced. Si ce n’est pas le cas, le compilateur vous avertit.If not, the compiler warns you.
  • Vous pouvez utiliser l’opérateur null-forgiving pour déclarer qu’une référence nullable n’est pas null.You can use the null-forgiving operator to declare that a nullable reference isn't null.

Dans un contexte d’annotation nullable activé, le caractère ? ajouté à un type référence déclare un type référence nullable.In an enabled nullable annotation context, the ? character appended to a reference type declares a nullable reference type. L' opérateur null-indulgent avec ! peut être ajouté à une expression pour déclarer que l’expression n’est pas null.The null-forgiving operator ! may be appended to an expression to declare that the expression isn't null.

Contexte d’avertissement nullableNullable warning context

Le contexte d’avertissement nullable est différent du contexte d’annotation nullable.The nullable warning context is distinct from the nullable annotation context. Des avertissements peuvent être activés, même lorsque les nouvelles annotations sont désactivées.Warnings can be enabled even when the new annotations are disabled. Le compilateur utilise l’analyse de flux statique pour déterminer l’état null de toutes les références.The compiler uses static flow analysis to determine the null state of any reference. L’état null est non null ou peut-être null quand le contexte d’avertissement nullable n’est pas désactivé.The null state is either not null or maybe null when the nullable warning context isn't disabled. Si vous déréférencez une référence quand le compilateur a déterminé qu’elle est peut-être null, le compilateur vous avertit.If you dereference a reference when the compiler has determined it's maybe null, the compiler warns you. L’état d’une référence est peut-être null, sauf si le compilateur peut déterminer une des deux conditions :The state of a reference is maybe null unless the compiler can determine one of two conditions:

  1. Une valeur non null a été assignée définitivement à la variable.The variable has been definitely assigned a non-null value.
  2. La variable ou l’expression a été vérifiée pour savoir si sa valeur est null avant de la référencer.The variable or expression has been checked against null before de-referencing it.

Le compilateur génère des avertissements lorsque vous déréférencez une variable ou une expression qui est peut-être null dans un contexte d’avertissement Nullable.The compiler generates warnings when you dereference a variable or expression that is maybe null in a nullable warning context. En outre, le compilateur génère des avertissements quand une variable de type référence non null reçoit une variable ou une expression de type null dans un contexte d’annotation Nullable activé.Furthermore, the compiler generates warnings when a nonnullable reference-type variable is assigned a maybe null variable or expression in an enabled nullable annotation context.

Les attributs décrivent des APIAttributes describe APIs

Vous ajoutez des attributs aux API qui fournissent au compilateur plus d’informations sur le moment où les arguments ou les valeurs de retour peuvent ou ne peuvent pas être null.You add attributes to APIs that provide the compiler more information about when arguments or return values can or can't be null. Vous pouvez en savoir plus sur ces attributs dans notre article dans la référence du langage couvrant les attributs Nullable.You can learn more about these attributes in our article in the language reference covering the nullable attributes. Ces attributs sont ajoutés aux bibliothèques .NET sur les versions actuelles et à venir.These attributes are being added to .NET libraries over current and upcoming releases. Les API les plus couramment utilisées sont mises à jour en premier.The most commonly used APIs are being updated first.

Pièges connusKnown pitfalls

Les tableaux et les structs qui contiennent des types référence sont des pièges connus dans la fonctionnalité de types référence Nullable.Arrays and structs that contain reference types are known pitfalls in nullable reference types feature.

StructuresStructs

Un struct qui contient des types référence n’acceptant pas les valeurs NULL permet de l’assigner default sans avertissement.A struct that contains non-nullable reference types allows assigning default for it without any warnings. Prenons l’exemple suivant :Consider the following example:

using System;

#nullable enable

public struct Student
{
    public string FirstName;
    public string? MiddleName;
    public string LastName;
}

public static class Program
{
    public static void PrintStudent(Student student)
    {
        Console.WriteLine($"First name: {student.FirstName.ToUpper()}");
        Console.WriteLine($"Middle name: {student.MiddleName.ToUpper()}");
        Console.WriteLine($"Last name: {student.LastName.ToUpper()}");
    }

    public static void Main() => PrintStudent(default);
}

Dans l’exemple précédent, il n’y a pas d’avertissement dans PrintStudent(default) tandis que les types de référence non Nullable FirstName et LastName sont null.In the preceding example, there is no warning in PrintStudent(default) while the non-nullable reference types FirstName and LastName are null.

Un autre cas plus courant est lorsque vous traitez des structs génériques.Another more common case is when you deal with generic structs. Prenons l’exemple suivant :Consider the following example:

#nullable enable

public struct Foo<T>
{
    public T Bar { get; set; }
}

public static class Program
{
    public static void Main()
    {
        string s = default(Foo<string>).Bar;
    }
}

Dans l’exemple précédent, la propriété Bar va être null au moment de l’exécution et elle est assignée à une chaîne non Nullable sans avertissement.In the preceding example, the property Bar is going to be null at runtime, and it's assigned to non-nullable string without any warnings.

TableauxArrays

Les tableaux sont également un piège connu dans les types de référence Nullable.Arrays are also a known pitfall in nullable reference types. Prenons l’exemple suivant qui ne génère pas d’avertissements :Consider the following example which doesn't produce any warnings:

using System;

#nullable enable

public static class Program
{
    public static void Main()
    {
        string[] values = new string[10];
        string s = values[0];
        Console.WriteLine(s.ToUpper());
    }
}

Dans l’exemple précédent, la déclaration du tableau indique qu’elle contient des chaînes qui n’acceptent pas les valeurs NULL, tandis que ses éléments sont tous initialisés à la valeur null.In the preceding example, the declaration of the array shows it holds non-nullable strings, while its elements are all initialized to null. Ensuite, s une valeur null est assignée à la variable (le premier élément du tableau).Then, the variable s is assigned a null value (the first element of the array). Enfin, la variable s est déréférencée et provoque une exception Runtime.Finally, the variable s is dereferenced causing a runtime exception.

Voir aussiSee also