C# Types nullables
En C#,int、float、bool、DateTimeetc. sont destypes valeur, ils doivent avoir une valeur par défaut et ne peuvent pas êtrenull:
int a = null; // 编译错误:无法将 null 转换为 int
Types nullablesrésolvent ce problème—il donne aux types valeur un état supplémentaire "aucune valeur" (c.-à-d.,null), ce qui est très utile dans les scénarios où des données peuvent être manquantes, comme les champs de base de données et les valeurs de retour d'API.
La déclaration est très simple : ajoutez un?:
int? a = null; // 合法 int? b = 42; // 合法
iciint?OuiNullable<int>sucre syntaxique (forme abrégée), les deux sont complètement équivalents :
Nullable<int> a = null; // 完整写法 int? a = null; // 简写,效果相同
Le diagramme suivant montre comment les types nullables fonctionnent en mémoire—ils utilisent un indicateur booléen supplémentaire pour enregistrer "si une valeur existe" :
La différence entre le point d'interrogation simple ? et le double point d'interrogation ??
Deux opérateurs liés aux types nullable en C# sont souvent utilisés ensemble, mais ont des significations complètement différentes :
| Opérateurs | Name | Objectif | Exemple |
|---|---|---|---|
? |
Modificateur de type nullable | Rend les types valeur capables d'êtrenull |
int? i = 3;Équivalent àNullable<int> i = new Nullable<int>(3); |
?? |
Opérateur de coalescence nulle | Lorsque la variable estnullfournir une valeur par défaut lorsque |
int result = i ?? 0; |
Une comparaison simple :
int i; // 普通值类型,默认值为 0,永远不能是 null int? ii; // 可空类型,默认值为 null
Déclaration et affectation de types nullable
Syntaxe de déclaration
<data_type>? <variable_name> = null;
Par exemple :
int? age = null; double? temperature = 36.6; bool? isActive = new bool?(); // 显式构造,默认为 null DateTime? birthday = null;
Nullable<T>peut représenter la plage normale de son type valeur sous-jacent, plus unenullValeur. Par exemple,Nullable<int>peut être-2,147,483,648à2,147,483,647n'importe quel entier entre les deux, ounull。
Exemple complet
Exemple
namespace NullableDemo
{
class Program
{
static void Main(string[] args)
{
// Déclarer des variables nullables de différents types
int? num1 = null;
int? num2 = 45;
double? num3 = new double?(); // null
double? num4 = 3.14157;
bool? boolVal = new bool?(); // null
// Afficher la valeur (null sera affiché comme une chaîne vide)
Console.WriteLine($"num1 = {num1 ?? 0}"); // 0
Console.WriteLine($"num2 = {num2 ?? 0}"); // 45
Console.WriteLine($"num3 = {num3 ?? 0.0}"); // 0
Console.WriteLine($"num4 = {num4 ?? 0.0}"); // 3.14157
Console.WriteLine($"boolVal = {boolVal}"); // (vide)
}
}
}
Résultat de sortie :
num1 = 0 num2 = 45 num3 = 0 num4 = 3.14157 boolVal =
Opérateur de coalescence nulle (??)
??opérateur est utilisé pour fournir unevaleur par défaut de repli. Lorsque le côté gauche n'est pasnulllorsqu'il n'est pas null, retourne la valeur de gauche ; sinon, retourne la valeur de droite :
<表达式1> ?? <表达式2>
- if
<表达式1>n'est pasnull, retourne<表达式1>; - sinon retourne
<表达式2>。
À partir de C# 8.0, vous pouvez également utiliser??=(opérateur d'affectation de coalescence nulle), uniquement lorsque la variable estnullAffecter uniquement lorsque :
int? x = null; x ??= 10; // x 为 null,赋值为 10 x ??= 20; // x 已有值 10,不再赋值
Exemple
namespace NullableDemo
{
class Program
{
static void Main(string[] args)
{
double? num1 = null;
double? num2 = 3.14157;
// ?? fournit une valeur par défaut
double result1 = num1 ?? 5.34; // num1 est null → renvoie 5.34
double result2 = num2 ?? 5.34; // num2 a une valeur → renvoie 3.14157
Console.WriteLine($"num1 ?? 5.34 = {result1}"); // 5.34
Console.WriteLine($"num2 ?? 5.34 = {result2}"); // 3.14157
// Utilisation chaînée : fournir plusieurs valeurs alternatives
int? a = null;
int? b = null;
int? c = 42;
int value = a ?? b ?? c ?? 0; // Essayer successivement, finir par obtenir 42
Console.WriteLine($"a ?? b ?? c ?? 0 = {value}"); // 42
}
}
}
Résultat de sortie :
num1 ?? 5.34 = 5.34 num2 ?? 5.34 = 3.14157 a ?? b ?? c ?? 0 = 42
Propriétés et méthodes courantes des types nullables
| membre | Description | Exemple |
|---|---|---|
.HasValue |
Vérifier si la variable a une valeur (renvoiebool) |
if (num.HasValue) { ... } |
.Value |
Obtenir la valeur réelle (si elle estnullLèvera une exceptionInvalidOperationException) |
int x = num.Value; |
.GetValueOrDefault() |
Obtenir la valeur en toute sécurité ; si elle estnullRetourne la valeur par défaut du type (comme0) |
num.GetValueOrDefault() |
.GetValueOrDefault(T) |
Obtenir la valeur en toute sécurité ; si elle estnullRetourne la valeur par défaut spécifiée |
num.GetValueOrDefault(100) |
?? |
Opérateur de coalescence nulle (sucre syntaxique, équivalent àGetValueOrDefault) |
int result = num ?? 100; |
Exemple
namespace NullableDemo
{
class Program
{
static void Main(string[] args)
{
int? num = null;
// HasValue + Value (approche traditionnelle)
if (num.HasValue)
Console.WriteLine($"Valeur : {num.Value}");
else
Console.WriteLine("num n'a pas de valeur");
// Obtenir la valeur par défaut en toute sécurité
Console.WriteLine(num.GetValueOrDefault()); // 0
Console.WriteLine(num.GetValueOrDefault(99)); // 99
Console.WriteLine(num ?? 99); // 99 (notation équivalente)
// ⚠ Remarque : accéder directement à .Value lèvera une exception
// int x = num.Value; // InvalidOperationException!
}
}
}
Scénarios d'application pratiques
Les types nullables sont très courants dans le développement réel, en particulier lorsqu'il s'agit de données potentiellement manquantes :
Mappage des champs de base de données
Les champs de la base de données peuvent êtreNULL, les types nullables peuvent correspondre précisément :
| ID utilisateur | Âge | S'il est actif |
|---|---|---|
| 1 | 28 | vrai |
| 2 | null | false |
int? age = GetUserAgeFromDB(userId: 2);
// 安全处理 null
string display = age.HasValue
? $"用户年龄:{age.Value}"
: "年龄未知";
// 或者更简洁的写法
string display2 = $"用户年龄:{age ?? 0}";
Paramètres optionnels et configuration
// 配置项可能未设置
int? timeout = GetConfigValue("timeout");
int actualTimeout = timeout ?? 30; // 未设置时使用默认值 30 秒
Vérifications null chaînées (C# 6.0+)
// 使用 ?. 运算符安全访问可能为 null 的对象 string? name = user?.Address?.City?.Name; // 如果 user、Address、City 中任何一个为 null,结果就是 null,不会抛异常
Résumé
| Fonctionnalités | Exemple | Description |
|---|---|---|
| Définition des types nullables | int? x = null; |
Équivalent àNullable<int> |
| Déterminer si une valeur existe | x.HasValue |
returntrueoufalse |
| Obtenir la valeur (unsafe) | x.Value |
S'il estnullLèvera une exceptionInvalidOperationException |
| Obtenir la valeur par défaut | x ?? 0 |
S'il estnullRetourner la valeur de droite |
| Obtenir la valeur par défaut spécifiée | x.GetValueOrDefault(10) |
S'il estnullRetourner 10 |
| Affectation de coalescence null | x ??= 10 |
Uniquement lorsquexestnullaffecter lorsque (C# 8.0+) |
| Accès de navigation sécurisé | user?.Name |
ifuserestnullpuis retournernull(C# 6.0+) |
les « types de référence nullables » de C# 8.0
À partir de C# 8.0, ... a été introduit.Types de référence nullablescelui-ci et celui introduit dans cet articletypes valeur nullablessont deux mécanismes différents :
| Élément de comparaison | Types valeur nullables | Types référence nullables |
|---|---|---|
| Exemple | int? |
string? |
| Objet cible | Type valeur (int、bool、structetc.) |
Types référence (string、classtableaux, etc.) |
| Approche d'implémentation | Au moment de l'exécution viaNullable<T>Implémentation de struct |
Analyse statique du compilateur, ne change pas le comportement à l'exécution |
| État par défaut | a toujours existé (depuis C# 1.0) | Doivent être activés dans le projet<Nullable>enable</Nullable> |
| vérification de null | use.HasValuePrise de décision |
Le compilateur émet des avertissements (et non des erreurs) |
autres extensionsLes types de référence nullables sont un outil de vérification de sûreté à la compilation—cela ne change pas le comportement d’exécution du programme, mais lorsque le code peut produire
NullReferenceExceptiondes avertissements du compilateur sont émis, vous aidant à découvrir des problèmes potentiels pendant la phase de développement.