Partager via


Types valeur pouvant accepter la valeur Null (référence C#)

Un type valeur pouvant accepter la valeur NullT? représente toutes les valeurs de son type valeurT sous-jacent et une valeur Null supplémentaire. Par exemple, vous pouvez affecter l’une des trois valeurs suivantes à une bool? variable : true, falseou null. Un type T valeur sous-jacent ne peut pas être un type valeur nullable lui-même.

Le langage C# documente la version la plus récente de la langue C#. Il contient également la documentation initiale des fonctionnalités dans les préversions publiques pour la prochaine version du langage.

La documentation identifie toute fonctionnalité introduite en premier dans les trois dernières versions de la langue ou dans les préversions publiques actuelles.

Conseil / Astuce

Pour savoir quand une fonctionnalité a été introduite en C#, consultez l’article sur l’historique des versions du langage C#.

Tout type de valeur nullable est une instance de la structure générique System.Nullable<T>. Vous pouvez faire référence à un type valeur nullable avec un type T sous-jacent dans l’un des formulaires interchangeables suivants : Nullable<T> ou T?.

En règle générale, utilisez un type valeur nullable lorsque vous devez représenter la valeur non définie d’un type valeur sous-jacent. Par exemple, une variable booléenne ou bool, ne peut être que true ou false. Toutefois, dans certaines applications, une valeur de variable peut être non définie ou manquante. Par exemple, un champ de base de données peut contenir true ou false, ou il peut contenir aucune valeur du tout, autrement dit. NULL Vous pouvez utiliser le type bool? dans ce scénario.

Déclaration et affectation

Étant donné qu’un type valeur est implicitement convertible en type valeur nullable correspondant, vous pouvez affecter une valeur à une variable d’un type valeur nullable comme vous le faites pour son type valeur sous-jacent. Vous pouvez également affecter la valeur null. Par exemple :

double? pi = 3.14;
char? letter = 'a';

int m2 = 10;
int? m = m2;

bool? flag = null;

// An array of a nullable value type:
int?[] arr = new int?[10];

La valeur par défaut d’un type valeur nullable représente null. Il s’agit d’une instance dont Nullable<T>.HasValue la propriété retourne false.

Examen d’une instance d’un type valeur nullable

Pour vérifier une instance d’un type valeur nullable et null obtenir une valeur d’un type sous-jacent, utilisez l’opérateuris avec un modèle de type :

int? a = 42;
if (a is int valueOfA)
{
    Console.WriteLine($"a is {valueOfA}");
}
else
{
    Console.WriteLine("a does not have a value");
}
// Output:
// a is 42

Vous pouvez toujours utiliser les propriétés en lecture seule suivantes pour vérifier et obtenir une valeur d’une variable de type valeur nullable :

L’exemple suivant utilise la HasValue propriété pour vérifier si la variable contient une valeur avant de l’afficher :

int? b = 10;
if (b.HasValue)
{
    Console.WriteLine($"b is {b.Value}");
}
else
{
    Console.WriteLine("b does not have a value");
}
// Output:
// b is 10

Vous pouvez également comparer une variable de type nullable avec null au lieu d’utiliser la propriété HasValue, comme le montre l’exemple suivant :

int? c = 7;
if (c != null)
{
    Console.WriteLine($"c is {c.Value}");
}
else
{
    Console.WriteLine("c does not have a value");
}
// Output:
// c is 7

Conversion d’un type valeur nullable en type sous-jacent

Si vous souhaitez affecter une valeur d’un type valeur nullable à une variable de type valeur non nullable, vous devrez peut-être spécifier la valeur à affecter à la place de null. Utilisez l’opérateur ??de fusion null pour le faire. Vous pouvez également utiliser la Nullable<T>.GetValueOrDefault(T) méthode à la même fin :

int? a = 28;
int b = a ?? -1;
Console.WriteLine($"b is {b}");  // output: b is 28

int? c = null;
int d = c ?? -1;
Console.WriteLine($"d is {d}");  // output: d is -1

Si vous souhaitez utiliser la valeur par défaut du type valeur sous-jacent à la place de null, utilisez la méthode Nullable<T>.GetValueOrDefault().

Vous pouvez également convertir explicitement un type valeur nullable en type non nullable, comme le montre l’exemple suivant :

int? n = null;

//int m1 = n;    // Doesn't compile
int n2 = (int)n; // Compiles, but throws an exception if n is null

Au moment de l’exécution, si la valeur d’un type nullable estnull, le cast explicite lève uneInvalidOperationException.

Un type valeur non-nullable T est implicitement converti en type valeur nullable correspondant T?.

Opérateurs levés

Un type T? valeur nullable prend en charge les opérateurs unaires et binaires prédéfinis ou tous les opérateurs surchargés qu’un type T valeur prend en charge. Ces opérateurs, également appelés opérateurs levés, retournent null si un ou les deux opérandes sont null. Sinon, l’opérateur utilise les valeurs contenues de ses opérandes pour calculer le résultat. Par exemple :

int? a = 10;
int? b = null;
int? c = 10;

a++;        // a is 11
a = a * c;  // a is 110
a = a + b;  // a is null

Notes

Pour le type bool?, les opérateurs & et | prédéfinis ne suivent pas les règles décrites dans cette section : le résultat d’une évaluation peut être non null, même si l’un des opérandes est null. Pour plus d’informations, voir la section Opérateurs logiques booléens Nullable de l’article Opérateurs logiques booléens.

Pour les opérateurs< de comparaison, >, <=et >=, si un ou les deux opérandes sont null, le résultat est false. Sinon, les valeurs contenues des opérandes sont comparées. Ne supposez pas que parce qu’une comparaison particulière (par exemple, <=) retourne false, la comparaison opposée (>) retourne true. L’exemple suivant montre que 10 n’est

  • ni supérieur ou égal à null
  • ni inférieur à null
int? a = 10;
Console.WriteLine($"{a} >= null is {a >= null}");
Console.WriteLine($"{a} < null is {a < null}");
Console.WriteLine($"{a} == null is {a == null}");
// Output:
// 10 >= null is False
// 10 < null is False
// 10 == null is False

int? b = null;
int? c = null;
Console.WriteLine($"null >= null is {b >= c}");
Console.WriteLine($"null == null is {b == c}");
// Output:
// null >= null is False
// null == null is True

Pour l’opérateur ==d’égalité, si les deux opérandes sont null, le résultat est true. Si un seul des opérandes est null, le résultat est false. Sinon, les valeurs contenues des opérandes sont comparées.

Pour l’opérateur !=d’inégalité, si les deux opérandes sont null, le résultat est false. Si un seul des opérandes est null, le résultat est true. Sinon, les valeurs contenues des opérandes sont comparées.

Si une conversion définie par l’utilisateur existe entre deux types valeur, la même conversion peut également être utilisée entre les types valeur nullable correspondants.

Boxing et unboxing

Les règles suivantes s’appliquent lorsque vous boxez une instance d’un type T?valeur nullable :

  • Si HasValue elle est retournée false, l’opération de boxe retourne la référence Null.
  • Si HasValue elle est retournée, l’opération de boxe renvoie truela valeur correspondante du type Tvaleur sous-jacent, et non l’instance de Nullable<T>.

Vous pouvez effectuer l’unboxing du type valeur T vers le type T? correspondant, comme le montre l’exemple suivant :

int a = 41;
object aBoxed = a;
int? aNullable = (int?)aBoxed;
Console.WriteLine($"Value of aNullable: {aNullable}");

object aNullableBoxed = aNullable;
if (aNullableBoxed is int valueOfA)
{
    Console.WriteLine($"aNullableBoxed is boxed int: {valueOfA}");
}
// Output:
// Value of aNullable: 41
// aNullableBoxed is boxed int: 41

Guide pratique pour identifier un type valeur nullable

L’exemple suivant montre comment déterminer si une instance System.Type représente un type valeur nullable construit, autrement dit, le type System.Nullable<T> avec un paramètre de type spécifié T :

Console.WriteLine($"int? is {(IsNullable(typeof(int?)) ? "nullable" : "non nullable")} value type");
Console.WriteLine($"int is {(IsNullable(typeof(int)) ? "nullable" : "non-nullable")} value type");

bool IsNullable(Type type) => Nullable.GetUnderlyingType(type) != null;

// Output:
// int? is nullable value type
// int is non-nullable value type

Comme l’illustre l’exemple, vous utilisez l’opérateur typeof pour créer une instance System.Type.

Si vous souhaitez déterminer si une instance est d’un type valeur nullable, n’utilisez pas la Object.GetType méthode pour obtenir une Type instance à tester à l’aide du code précédent. Quand vous appelez la méthode Object.GetType sur une instance d’un type valeur nullable, l’instance est boxed à Object. Étant donné que la boxe d’une instance non null d’un type valeur nullable équivaut à boxer une valeur du type sous-jacent, GetType retourne une Type instance qui représente le type sous-jacent d’un type valeur Nullable :

int? a = 17;
Type typeOfA = a.GetType();
Console.WriteLine(typeOfA.FullName);
// Output:
// System.Int32

Par ailleurs, n’utilisez pas l’opérateur is pour déterminer si une instance est d’un type valeur nullable. Comme l’illustre l’exemple suivant, vous ne pouvez pas distinguer les types d’une instance de type valeur nullable et de son instance de type sous-jacente à l’aide de l’opérateur is :

int? a = 14;
if (a is int)
{
    Console.WriteLine("int? instance is compatible with int");
}

int b = 17;
if (b is int?)
{
    Console.WriteLine("int instance is compatible with int?");
}
// Output:
// int? instance is compatible with int
// int instance is compatible with int?

Utilisez plutôt la Nullable.GetUnderlyingType méthode du premier exemple et de l’opérateur typeof pour vérifier si une instance est d’un type valeur nullable.

Notes

Les méthodes décrites dans cette section ne s’appliquent pas aux types de référence nullables.

spécification du langage C#

Pour plus d’informations, consultez les sections suivantes de la spécification du langage C# :

Voir aussi