Types valeur pouvant accepter la valeur Null (référence C#)
Un type valeur Nullable représente toutes les valeurs de son type valeur sous-jacent et une valeur null supplémentaire. Par exemple, vous pouvez assigner l’une des trois valeurs suivantes à une bool?
variable : true
, false
ou null
. Un type T
valeur sous-jacent ne peut pas être un type valeur Nullable lui-même.
Notes
C# 8,0 introduit la fonctionnalité de types référence Nullable. Pour plus d’informations, consultez types de référence Nullable. Les types valeur Nullable sont disponibles à partir de C# 2.
Tout type 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 général, vous utilisez un type valeur Nullable lorsque vous devez représenter la valeur indéfinie d’un type valeur sous-jacent. Par exemple, une variable booléenne, ou bool
, ne peut être true
que ou false
. Toutefois, dans certaines applications, une valeur de variable peut être indéfinie ou manquante. Par exemple, un champ de base de données peut contenir true
ou false
, ou il ne peut contenir aucune valeur, autrement dit, NULL
. Vous pouvez utiliser le bool?
type dans ce scénario.
Déclaration et affectation
Comme un type valeur est implicitement convertible en type valeur Nullable correspondant, vous pouvez assigner une valeur à une variable d’un type valeur Nullable comme vous le feriez pour son type valeur sous-jacent. Vous pouvez également affecter la null
valeur. 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
, autrement dit, une instance dont Nullable<T>.HasValue la propriété retourne false
.
Examen d’une instance d’un type valeur Nullable
À compter de C# 7,0, vous pouvez utiliser l' opérateur avec un modèle de type pour examiner à la fois une instance d’un type de valeur Nullable pour null
et récupérer une valeur d’un type sous-jacent :
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 examiner et obtenir la valeur d’une variable de type valeur Nullable :
Nullable<T>.HasValue indique si une instance d’un type valeur Nullable a une valeur de son type sous-jacent.
Nullable<T>.Value obtient la valeur d’un type sous-jacent si HasValue est
true
. Si HasValue estfalse
, la propriété Value lève une InvalidOperationException.
L’exemple suivant utilise la HasValue
propriété pour déterminer 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 d’un type valeur Nullable avec null
au lieu d’utiliser la HasValue
propriété, 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 un type sous-jacent
Si vous souhaitez assigner une valeur d’un type valeur Nullable à une variable de type valeur n’acceptant pas les valeurs NULL, vous devrez peut-être spécifier la valeur à assigner à la place de null
. Utilisez l' opérateur de fusion Null pour effectuer cette opération (vous pouvez également utiliser la Nullable<T>.GetValueOrDefault(T) méthode dans le même but) :
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 , utilisez la Nullable<T>.GetValueOrDefault() méthode.
Vous pouvez également effectuer un cast explicite d’un type valeur Nullable vers un 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 valeur Nullable est null
, le cast explicite lève une InvalidOperationException .
Un type T
valeur n’acceptant pas les valeurs NULL est implicitement convertible en type T?
valeur Nullable correspondant.
Opérateurs levés
Les opérateurs unaires et binaires prédéfinis ou tous les opérateurs surchargés pris en charge par un type valeur sont également pris en charge par le type T?
valeur Nullable correspondant. Ces opérateurs, également appelés opérateurs levés, produisent si l’un des opérandes ou les deux 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 bool?
type, les opérateurs prédéfinis &
et |
ne suivent pas les règles décrites dans cette section : le résultat d’une évaluation d’opérateur 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 l’un des opérandes ou les deux sont null
, le résultat est false
; sinon, les valeurs contenues des opérandes sont comparées. Ne partez pas du principe que parce qu’une comparaison spécifique (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.
S’il existe une conversion définie par l’utilisateur entre deux types valeur, la même conversion peut également être utilisée entre les types valeur Nullable correspondants.
Boxing et unboxing
Une instance d’un type T?
valeur Nullable est T?
comme suit :
- Si HasValue retourne
false
, la référence null est générée. - Si HasValue retourne
true
, la valeur correspondante du typeT
valeur sous-jacent est boxed, et non l’instance de Nullable<T> .
Vous pouvez convertir une valeur boxed d’un type T
valeur en type T?
valeur Nullable 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
Comment identifier un type valeur Nullable
L’exemple suivant montre comment déterminer si une System.Type instance représente un type valeur Nullable construit, autrement dit, le System.Nullable<T> type avec un paramètre T
de type spécifié :
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 le montre l’exemple, vous utilisez l’opérateur typeof pour créer une instance.
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 avec le code précédent. Quand vous appelez la Object.GetType méthode sur une instance d’un type valeur Nullable, l’instance est Object.GetType en Object . La conversion boxing d’une instance non null d’un type valeur Nullable équivaut au boxing d’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
En outre, n’utilisez pas l’opérateur is pour déterminer si une instance est d’un type valeur Nullable. Comme le montre l’exemple suivant, vous ne pouvez pas distinguer les types d’une instance de type valeur Nullable et son instance de type sous-jacent avec l' is
opérateur :
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 à la place le Nullable.GetUnderlyingType du premier exemple et l’opérateur Nullable.GetUnderlyingType pour vérifier si une instance est d’un type valeur Nullable.
Notes
Les méthodes décrites dans cette section ne sont pas applicables dans le cas des types référence Nullable.
spécification du langage C#
Pour plus d’informations, consultez les sections suivantes de la spécification du langage C# :
- Types Nullable
- Opérateurs levés
- Conversions Nullable implicites
- Conversions Nullable explicites
- Opérateurs de conversion levés