Opérateur conditionnel Null C#

Conditionnelles en 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

// Approche traditionnelle - contrôles de null fastidieux
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

class Person
{
    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

class Calculator
{
    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

class DataContainer
{
    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[] numbers = null;
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

Dictionary<string, string> dictionary = null;
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

using System;

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

Person person = null;
string displayName = person?.Name ?? (person != null ? "Utilisateur anonyme" : “L'utilisateur n'existe pas”);

3. Utilisation dans les requêtes LINQ

Exemple

List<Person> people = new List<Person>
{
    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

// Lier des données en toute sécurité dans WPF ou ASP.NET
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 class ApiResponse<T>
{
    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 class AppConfig
{
    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

Person person = new Person { Name = "Zhang San" };

// 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

// Non recommandé - surutilisé, difficile à comprendre
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

// Ces deux approches ont des performances comparables
// 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

// Méthode traditionnelle
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

// code d'origine
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 class Order
{
    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

// Créer un exemple complet démontrant l'application de l'opérateur conditionnel Null dans un projet réel.
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; }
}

Conditionnelles en C#

autres extensions