C# List Remove - Évitez les pièges courants et supprimez efficacement

Noël Besnard .

6 mars 2026

Code C# affiché sur un écran d'ordinateur, avec des lignes de code colorées sur fond noir.

Supprimer des éléments dans une liste C# paraît simple, mais en pratique la bonne méthode dépend de ce que tu sais déjà sur l’élément à retirer: sa valeur, son index ou une condition. Le sujet derrière c# list remove se joue surtout entre Remove, RemoveAt, RemoveRange, RemoveAll et Clear, avec des pièges très concrets sur l’égalité, les performances et l’itération. Je vais te montrer comment choisir la bonne approche, quand le code devient fragile, et comment éviter les erreurs qui reviennent sans cesse dans les projets C#.

Les points essentiels à garder avant de modifier une List

  • Remove supprime la première occurrence d’une valeur et renvoie un booléen.
  • RemoveAt travaille par index et décale tous les éléments qui suivent.
  • RemoveAll est le bon choix quand tu veux filtrer selon une règle métier.
  • foreach et suppression ne font pas bon ménage si tu modifies la collection pendant l’itération.
  • Clear vide la liste, mais ne réduit pas forcément sa capacité mémoire.
  • Pour les objets personnalisés, l’égalité compte autant que la méthode choisie.

Ce que signifie vraiment supprimer dans une List

Dans une List, supprimer un élément ne veut pas seulement dire “effacer une case”. La liste se compacte immédiatement: les éléments situés après la suppression sont renumérotés et glissent vers la gauche. C’est pour ça que les index changent tout de suite, et c’est aussi la raison pour laquelle plusieurs opérations de suppression peuvent coûter plus cher qu’on ne l’imagine.

La documentation Microsoft rappelle aussi un point souvent négligé: Remove s’appuie sur l’égalité par défaut de T. Autrement dit, si tu manipules une classe personnalisée, deux instances qui “se ressemblent” ne seront pas forcément considérées comme identiques si Equals et GetHashCode ne sont pas cohérents. En clair, la suppression dépend autant de la structure de tes données que de la méthode appelée.

Une fois cette mécanique en tête, le premier cas d’usage devient très concret: retirer une valeur précise sans toucher au reste.

Retirer la première occurrence d’une valeur

Remove est la méthode la plus lisible quand tu connais la valeur exacte à supprimer. Elle enlève la première occurrence trouvée, puis renvoie true si la suppression a réussi, ou false si la valeur n’était pas présente. C’est pratique pour du code simple, des doublons tolérés, ou des listes de chaînes et d’objets dont l’égalité est bien définie.

var fruits = new List { "Pomme", "Banane", "Poire", "Banane" };

if (fruits.Remove("Banane"))
{
    Console.WriteLine("Première occurrence supprimée.");
}

Console.WriteLine(string.Join(", ", fruits));

Ce petit détail change beaucoup de choses: si ta liste contient plusieurs fois la même valeur, une seule disparaît. Je garde donc Remove pour les suppressions ponctuelles, pas pour vider une catégorie entière. Quand l’élément est connu par sa position plutôt que par sa valeur, la logique devient différente.

Supprimer par position ou par bloc

Quand tu as un index fiable, RemoveAt est plus direct. L’index est en base zéro, donc le premier élément est à 0, le deuxième à 1, et ainsi de suite. La méthode retire un seul élément, puis décale le reste. Microsoft indique aussi que l’opération est en O(n), parce que les éléments après la position supprimée doivent être déplacés.

RemoveRange sert au même genre de travail, mais sur un bloc contigu. C’est utile quand tu veux enlever plusieurs éléments d’un coup à partir d’un point de départ précis. Les deux méthodes exigent des bornes valides: un index invalide ou une plage impossible déclenche une exception, donc je les utilise surtout quand l’état de la liste est bien maîtrisé.

var items = new List { "A", "B", "C", "D", "E" };

items.RemoveAt(2); // retire "C"

var more = new List { "A", "B", "C", "D", "E" };
more.RemoveRange(1, 2); // retire "B" et "C"

Je préfère cette famille de méthodes quand le besoin est “structurel”: je sais exactement où retirer, et je veux le faire sans introduire une logique de filtrage plus compliquée. Dès que la règle dépend d’un test métier, RemoveAll devient généralement plus propre.

Code C# montrant diverses initialisations de listes, y compris comment gérer un c# list remove.

Supprimer plusieurs éléments selon une condition

RemoveAll est la méthode que j’utilise le plus souvent dès qu’il faut filtrer une liste. Elle prend un predicat, c’est-à-dire une fonction qui retourne true ou false selon qu’un élément doit être retiré ou non. La méthode parcourt la liste, supprime tous les éléments qui matchent et renvoie le nombre total d’éléments retirés.

var users = new List
{
    new User("Alice", true),
    new User("Nadia", false),
    new User("Lucas", true),
    new User("Mina", false)
};

int removed = users.RemoveAll(u => !u.IsActive);

Console.WriteLine($"{removed} compte(s) supprimé(s).");

Ce pattern est intéressant parce qu’il traduit directement une règle métier: “garder les utilisateurs actifs”, “retirer les fichiers expirés”, “supprimer les produits hors stock”. La documentation Microsoft montre que RemoveAll traverse la liste du début à la fin et applique la condition à chaque élément, ce qui en fait une bonne réponse pour la plupart des filtres simples. Le vrai piège, lui, n’est pas la méthode: c’est la manière dont on la combine avec l’itération.

Les erreurs qui cassent souvent la suppression

La plus classique reste la modification d’une collection pendant un foreach. Microsoft le documente clairement: si tu ajoutes ou supprimes des éléments pendant l’itération, tu risques une InvalidOperationException avec un message du type “Collection was modified; enumeration operation may not execute.” En pratique, ça casse le programme au moment où tu t’y attends le moins.

// Mauvaise idée : la collection est modifiée pendant foreach.
foreach (var item in items)
{
    if (ShouldRemove(item))
    {
        items.Remove(item);
    }
}

Quand je dois absolument supprimer en parcourant la liste manuellement, je pars à rebours avec un for. L’astuce est simple: comme les éléments se décalent après une suppression, parcourir de la fin vers le début évite de sauter un élément ou de dérégler l’index courant.

for (int i = items.Count - 1; i >= 0; i--)
{
    if (ShouldRemove(items[i]))
    {
        items.RemoveAt(i);
    }
}

Dans beaucoup de cas, je ne m’embête même pas avec ça: si la règle tient en une expression, RemoveAll est plus lisible et plus sûr. Une fois les pièges identifiés, le plus utile reste de comparer les méthodes entre elles pour choisir vite et juste.

Quelle méthode j’utilise selon le besoin

Besoin Méthode Ce que ça fait Quand je la choisis
Retirer une valeur précise Remove(item) Supprime la première occurrence et renvoie un booléen Cas simple, doublons tolérés
Retirer un élément connu par son index RemoveAt(index) Supprime l’élément à la position indiquée Index stable, logique directe
Retirer un bloc contigu RemoveRange(index, count) Supprime plusieurs éléments d’un seul coup Plage connue à l’avance
Retirer selon une règle RemoveAll(predicate) Supprime tous les éléments qui respectent la condition Filtrage métier, nettoyage de liste
Vider complètement la liste Clear() Retire tous les éléments Réinitialisation totale

Mon réflexe est simple: si la règle tient en une phrase, je pars sur RemoveAll; si je connais une valeur exacte, j’utilise Remove; si j’ai un index sûr, je prends RemoveAt. Pour un vide complet, Clear() est le plus net, et il laisse souvent la capacité mémoire intacte, ce qui peut être utile si la liste doit repartir immédiatement. Le vrai critère de choix n’est donc pas la syntaxe, mais le type d’information que tu possèdes au moment de supprimer.

Et quand les suppressions deviennent fréquentes, je regarde aussi le volume. Par simple combinaison des coûts en O(n) annoncés par Microsoft, enchaîner beaucoup de Remove ou de RemoveAt peut finir par coûter cher, parfois jusqu’à un comportement proche de O(n²) si la liste est très sollicitée. C’est une déduction pratique, pas une règle abstraite, mais elle explique pourquoi je préfère souvent filtrer une fois plutôt que supprimer élément par élément.

La règle pratique que j’applique quand la liste devient sensible

Quand je sens que la suppression devient un point chaud, je reviens à une règle simple: je supprime selon le besoin réel, pas selon l’habitude. Pour un retrait unique, Remove. Pour une position, RemoveAt. Pour un bloc, RemoveRange. Pour une logique de filtre, RemoveAll. Et si le flux métier me pousse à supprimer énormément d’éléments, je n’hésite pas à reconstruire une nouvelle liste filtrée plutôt que d’empiler des suppressions unitaires.

C’est plus lisible, plus testable, et souvent plus prévisible en performance. Dans un codebase C# un peu sérieux, cette discipline évite déjà une bonne partie des bugs silencieux autour des index, des doublons et des collections modifiées au mauvais moment.

Questions fréquentes

Remove supprime la première occurrence d'une valeur spécifique de la liste, tandis que RemoveAt supprime l'élément à un index donné. Remove renvoie un booléen indiquant le succès, alors que RemoveAt ne renvoie rien mais lève une exception si l'index est invalide.
Utilisez RemoveAll pour supprimer plusieurs éléments basés sur une condition. C'est plus sûr et plus performant que de modifier la collection dans une boucle foreach, ce qui peut provoquer une InvalidOperationException. RemoveAll gère l'itération et la suppression en interne.
Lorsqu'un élément est supprimé, tous les éléments suivants dans la liste doivent être décalés pour combler le vide. Cette opération de décalage prend du temps proportionnel au nombre d'éléments restants après le point de suppression, d'où la complexité en O(n).
Pour éviter ces exceptions, ne modifiez pas une collection pendant que vous l'itérez avec un foreach. Utilisez RemoveAll pour des suppressions conditionnelles multiples, ou itérez à rebours avec une boucle for si vous devez supprimer des éléments individuellement par index ou valeur.
Clear() supprime tous les éléments de la liste, mais ne réduit pas nécessairement sa capacité mémoire sous-jacente. La liste reste "réservée" pour une certaine taille. Pour libérer la mémoire, vous devriez réinitialiser la liste (par exemple, `list = new List()`) ou appeler `TrimExcess()`.
Évaluer l'article

Moyenne: 0.0 / 5 · 0 évaluations

Tags

c# list remove supprimer élément list c# removeat c# removeall c# clear list c#
Autor Noël Besnard
Noël Besnard
Je m'appelle Noël Besnard et je possède 7 ans d'expérience dans le domaine de la technologie, en particulier en ce qui concerne le web, l'intelligence artificielle, les réseaux et la sécurité. Mon intérêt pour ces sujets a commencé dès mon adolescence, lorsque j'ai découvert le potentiel incroyable des nouvelles technologies pour transformer notre quotidien. J'aime explorer les défis que posent ces avancées et partager des solutions accessibles pour aider les lecteurs à mieux comprendre ces enjeux. Au fil des ans, j'ai eu l'occasion d'écrire sur divers aspects de la tech, en mettant l'accent sur la clarté et la précision. Je m'efforce de vérifier mes sources et de comparer les informations afin de proposer un contenu à jour et fiable. Mon objectif est de rendre des sujets complexes plus simples et compréhensibles, tout en suivant les dernières tendances du secteur. Je suis ravi de partager mes connaissances et d'accompagner les lecteurs dans leur exploration des technologies qui façonnent notre avenir.
Commentaires (0)
Ajouter un commentaire