Opérateur conditionnel Null C#
En programmation C#, gérernullla vérification des valeurs est une tâche courante mais sujette aux erreurs.
traditionnelnullLe code de vérification est souvent verbeux et fastidieux, et celui introduit par C# 6.0l'opérateur conditionnel Null(?.et?[]) simplifie grandement ce processus.
L'opérateur conditionnel Null est un sucre syntaxique introduit par C# 6.0, qui permet aux développeurs de vérifier d'abord si l'objet est null avant d'accéder à ses membres ou éléments.nullSi l'objet estnullle résultat de l'expression entière estnullet ne lèvera pas d'exceptionNullReferenceException。
Syntaxe de base
?.- Utilisé pour accéder aux membres (propriétés, méthodes, champs)?[]- Utilisé pour accéder aux indexeurs ou aux éléments de tableau
| Syntaxe | Description |
|---|---|
a?.b |
ifaSi non null, accédera.b; sinon retourner null |
a?.Method() |
ifaSi non null, appeler la méthode ; sinon, ne rien faire. |
a?[i] |
ifaSi non null, accéder à l'index ; sinon, retourner null. |
Pourquoi avons-nous besoin de l'opérateur conditionnel null ?
Problèmes avec les vérifications de null traditionnelles
Avant l'introduction de l'opérateur conditionnel null, les développeurs devaient écrire de manière verbeusenullVérifiez le code :
Exemple
string name = null;
if (person != null)
{
if (person.Address != null)
{
if (person.Address.City != null)
{
name = person.Address.City.Name;
}
}
}
Ce type de code est non seulement verbeux, mais aussi sujet aux erreurs et moins lisible.
Avantages de l'opérateur conditionnel null
À l'aide de l'opérateur conditionnel Null, la même logique peut être simplifiée en :
// 使用 Null 条件运算符 - 简洁明了 string name = person?.Address?.City?.Name;
Si une étape quelconque dans un appel chaîné est nullnull, toute l'expression renverranull, au lieu de lever une exception.
Explication détaillée de la syntaxe
1. Opérateur d'accès aux membres?.
?.L'opérateur est utilisé pour accéder en toute sécurité aux membres (propriétés, méthodes, champs) d'un objet.
Accéder à la propriété
Exemple
{
public string Name { get; set; }
public Address Address { get; set; }
}
class Address
{
public string City { get; set; }
}
// Accéder en toute sécurité aux propriétés
Person person = null;
string cityName = person?.Address?.City; // Retourne null, ne lève pas d'exception
Appeler la méthode
Exemple
{
public int Add(int a, int b) => a + b;
}
Calculator calc = null;
int? result = calc?.Add(5, 3); // Renvoie null, ne lève pas d'exception
Accès aux champs
Exemple
{
public string Value;
}
DataContainer container = null;
string value = container?.Value; // Renvoie null, ne lève pas d'exception
2. Opérateur d'accès aux éléments?[]
?[]L'opérateur est utilisé pour accéder en toute sécurité aux éléments d'un tableau ou d'une collection.
Accéder aux éléments d'un tableau
Exemple
int? firstNumber = numbers?[0]; // Renvoie null, ne lève pas d'exception
numbers = new int[] { 1, 2, 3 };
firstNumber = numbers?[0]; // retourne 1
Accès aux éléments du dictionnaire
Exemple
string value = dictionary?["key"]; // Retourne null, ne lève pas d'exception
dictionary = new Dictionary<string, string> { ["key"] = "value" };
value = dictionary?["key"]; // Retourne "value"
Combinaison avec d'autres opérateurs
| Opérateurs | Name | Objectif | Exemple | Valeur de retour |
|---|---|---|---|---|
? |
Déclaration de type nullable | Déclaration d'un type valeur nullable. | int? x = null; |
null |
?? |
Opérateur de coalescence null | Si le côté gauche est null, retourne le côté droit. | a ?? b |
b |
?. |
Opérateur conditionnel Null | Accès sécurisé aux membres | a?.b |
null ou la valeur de b |
?[] |
Opérateur d’index conditionnel Null | Accéder en toute sécurité aux tableaux ou collections | a?[i] |
null ou l’élément |
?: |
Opérateur conditionnel (ternaire) | Retourner différentes valeurs selon la condition | a ? b : c |
b ou c |
1. Avec l’opérateur de fusion Null??Combinaison
L’opérateur conditionnel Null est fréquemment combiné avec l’opérateur de fusion Null??Utilisez-les ensemble pour fournir une valeur par défaut :
Person person = null;
// 提供默认值
string cityName = person?.Address?.City ?? "未知城市";
Console.WriteLine(cityName); // 输出: 未知城市
person = new Person { Address = new Address { City = "北京" } };
cityName = person?.Address?.City ?? "未知城市";
Console.WriteLine(cityName); // 输出: 北京
Exemple
class Address
{
public string City { get; set; }
}
class Person
{
public string Name { get; set; }
public Address Address { get; set; }
public void SayHello()
{
Console.WriteLine($"Bonjour, je suis {Name}");
}
}
class Program
{
static void Main()
{
Person person = null;
// Accéder en toute sécurité aux propriétés
Console.WriteLine(person?.Name ?? "Utilisateur sans nom");
// Accéder en toute sécurité aux propriétés imbriquées
Console.WriteLine(person?.Address?.City ?? "Ville inconnue");
// Appeler des méthodes en toute sécurité
person?.SayHello();
// Accéder aux tableaux en toute sécurité
int[] arr = null;
Console.WriteLine(arr?[0] ?? -1);
}
}
Sortie :
未命名用户 未知城市 -1
2. Avec l'opérateur conditionnel?:Combinaison
Exemple
string displayName = person?.Name ?? (person != null ? "Utilisateur anonyme" : “L'utilisateur n'existe pas”);
3. Utilisation dans les requêtes LINQ
Exemple
{
new Person { Name = "Jean Dupont", Address = new Address { City = "Pékin" } },
new Person { Name = "Pierre Durand", Address = null },
null
};
// Accéder en toute sécurité aux propriétés pouvant être null
var cities = people
.Where(p => p?.Address?.City != null)
.Select(p => p.Address.City)
.ToList();
Scénarios d'application pratiques
Scénario 1 : Liaison de données et développement de l'interface utilisateur
Exemple
public string DisplayAddress => $"{Person?.Address?.City ?? "Ville inconnue"} - {Person?.Address?.Street ?? "Rue inconnue"}";
// Appeler la méthode en toute sécurité
button.Click += (s, e) =>
{
viewModel?.SaveCommand?.Execute(null);
};
Scénario 2 : Gestion des réponses API
Exemple
{
public T Data { get; set; }
public string Error { get; set; }
}
public class User
{
public string Name { get; set; }
public Profile Profile { get; set; }
}
public class Profile
{
public string AvatarUrl { get; set; }
}
// Gérer en toute sécurité la réponse de l'API
ApiResponse<User> response = GetUserFromApi();
string avatarUrl = response?.Data?.Profile?.AvatarUrl ?? "default-avatar.png";
Scénario 3 : Lecture de la configuration
Exemple
{
public DatabaseConfig Database { get; set; }
}
public class DatabaseConfig
{
public string ConnectionString { get; set; }
public int? Timeout { get; set; }
}
// Lire la configuration en toute sécurité
AppConfig config = LoadConfiguration();
string connectionString = config?.Database?.ConnectionString ?? "DefaultConnection";
int timeout = config?.Database?.Timeout ?? 30;
Considérations et bonnes pratiques
1. Types de valeur de retour
Lorsque vous utilisez l'opérateur conditionnel Null, vous devez faire attention au type de retour de l'expression :
Exemple
// Pour les types valeur, retourner Nullable<T>
int? nameLength = person?.Name?.Length; // Le type est int ?
// Pour les types de référence, retourner le type lui-même
string name = person?.Name; // Le type est string
2. Éviter la surutilisation
Bien que l'opérateur conditionnel Null soit pratique, il ne doit pas être surutilisé :
Exemple
var result = obj1?.Property1?.Method1()?.Property2 ?? defaultValue;
// Recommandé - décomposer de manière appropriée, améliorer la lisibilité
var temp1 = obj1?.Property1;
var temp2 = temp1?.Method1();
var result = temp2?.Property2 ?? defaultValue;
3. Considérations sur les performances
L'opérateur conditionnel Null a des performances comparables à unenullvérification explicite, mais les appels chaînés créent des variables temporaires :
Exemple
// Méthode 1 : vérification traditionnelle
if (person != null && person.Address != null)
{
return person.Address.City;
}
// Méthode 2 : opérateur conditionnel Null
return person?.Address?.City;
4. Combinaison avec l'invocation d'événements
L'opérateur conditionnel Null est particulièrement adapté à l'invocation d'événements :
Exemple
public event EventHandler SomethingHappened;
protected virtual void OnSomethingHappened()
{
if (SomethingHappened != null)
{
SomethingHappened(this, EventArgs.Empty);
}
}
// Utilisation de l'opérateur conditionnel null - plus concis
protected virtual void OnSomethingHappened()
{
SomethingHappened?.Invoke(this, EventArgs.Empty);
}
Exercices pratiques
Exercice 1 : Refactorisation du code
Le code traditionnel suivantnullRefactoriser le code de vérification pour utiliser l'opérateur conditionnel Null :
Exemple
public string GetUserEmail(User user)
{
if (user != null)
{
if (user.Profile != null)
{
if (user.Profile.ContactInfo != null)
{
return user.Profile.ContactInfo.Email;
}
}
}
return "Aucune information sur l'email";
}
// Votre code refactorisé
public string GetUserEmail(User user)
{
return user?.Profile?.ContactInfo?.Email ?? "Aucune information sur l'email";
}
Exercice 2 : Gestion des données de collection
Exemple
{
public List<OrderItem> Items { get; set; }
public Customer Customer { get; set; }
}
public class OrderItem
{
public Product Product { get; set; }
public int Quantity { get; set; }
}
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
}
public class Customer
{
public string Name { get; set; }
}
// Écrire une méthode, obtenir en toute sécurité le nom du produit dans la commande
public string GetFirstProductName(Order order)
{
return order?.Items?.FirstOrDefault()?.Product?.Name ?? "Aucune information sur le produit";
}
Exercice 3 : Application complète
Exemple
public class ShoppingCart
{
public List<CartItem> Items { get; set; }
public decimal? CalculateTotal()
{
return Items?.Sum(item => item?.Product?.Price * item?.Quantity) ?? 0;
}
}
public class CartItem
{
public Product Product { get; set; }
public int? Quantity { get; set; }
}