Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Les données similaires peuvent souvent être gérées plus efficacement lorsqu’elles sont stockées et manipulées en tant que collection. Vous pouvez utiliser la System.Array classe ou les classes dans les System.Collectionsespaces de noms , System.Collections.GenericSystem.Collections.Concurrentet System.Collections.Immutable ajouter, supprimer et modifier des éléments individuels ou une plage d’éléments dans une collection.
Il existe deux types principaux de collections ; collections génériques et collections non génériques. Les collections génériques sont de type sécurisé au moment de la compilation. En raison de cela, les collections génériques offrent généralement de meilleures performances. Les collections génériques acceptent un paramètre de type lorsqu’ils sont construits. Il n’est pas nécessaire d’effectuer de conversion vers ou depuis le type Object lorsque vous ajoutez ou retirez des éléments de la collection. En outre, la plupart des collections génériques sont prises en charge dans les applications du Windows Store. Les collections non génériques stockent les éléments en tant que Object, nécessitent un transtypage, et la plupart ne sont pas prises en charge pour le développement d’applications Windows Store. Toutefois, vous pouvez voir des collections non génériques dans du code plus ancien.
Dans .NET Framework 4 et versions ultérieures, les collections de l'espace de noms System.Collections.Concurrent fournissent des opérations thread-safe efficaces pour accéder aux éléments de collection depuis plusieurs threads. Les classes de collection immuable de l’espace de noms System.Collections.Immutable (NuGet package) sont thread-safe, car les opérations sont effectuées sur une copie de la collection d’origine et celle-ci ne peut donc pas être modifiée.
Fonctionnalités courantes de collection
Toutes les collections fournissent des méthodes pour ajouter, supprimer ou rechercher des éléments dans la collection. En outre, toutes les collections qui implémentent directement ou indirectement l’interface ICollection ou l’interface ICollection<T> partagent ces fonctionnalités :
Possibilité d’énumérer la collection
Les collections .NET implémentent soit System.Collections.IEnumerable soit System.Collections.Generic.IEnumerable<T> pour permettre ainsi à la collection d’être itérée. Un énumérateur peut être considéré comme un pointeur mobile vers n’importe quel élément de la collection. L’instruction foreach, in et For Each...Next Instruction utilisent l’énumérateur exposé par la méthode GetEnumerator et masquent la complexité de la manipulation de l’énumérateur. En outre, toute collection qui implémente System.Collections.Generic.IEnumerable<T> est considérée comme un type interrogeable et peut être interrogée avec LINQ. Les requêtes LINQ fournissent un modèle courant pour accéder aux données. Ils sont généralement plus concis et lisibles que les boucles standard
foreachet fournissent des fonctionnalités de filtrage, de classement et de regroupement. Les requêtes LINQ peuvent également améliorer les performances. Pour plus d’informations, consultez LINQ to Objects (C#),LINQ to Objects (Visual Basic),Parallel LINQ (PLINQ), Introduction aux requêtes LINQ (C#) et Opérations de requête de base (Visual Basic).Possibilité de copier le contenu de la collection dans un tableau
Toutes les collections peuvent être copiées dans un tableau à l’aide de la
CopyTométhode. Toutefois, l’ordre des éléments dans le nouveau tableau est basé sur la séquence dans laquelle l’énumérateur les retourne. Le tableau résultant est toujours unidimensionnel avec une limite inférieure de zéro.
En outre, de nombreuses classes de collection contiennent les fonctionnalités suivantes :
Propriétés de capacité et de nombre
La capacité d’une collection est le nombre d’éléments qu’elle peut contenir. Le compte d'une collection est le nombre total d’éléments qu'elle contient réellement. Certaines collections masquent l'une de ces propriétés, voire les deux.
La plupart des collections augmentent automatiquement leur capacité lorsque la capacité actuelle est atteinte. La mémoire est réallouée et les éléments sont copiés depuis l'ancienne collection vers la nouvelle. Cette conception réduit le code requis pour utiliser la collection. Toutefois, les performances de la collection peuvent être affectées négativement. Par exemple, pour List<T>, si Count est inférieur à Capacity, l'ajout d'un élément est une opération O(1). Si la capacité doit être augmentée pour prendre en charge le nouvel élément, l’ajout d’un élément devient une opération O(
n), oùnest Count. La meilleure façon d’éviter les performances médiocres causées par plusieurs réaffectations consiste à définir la capacité initiale pour être la taille estimée de la collection.A BitArray est un cas spécial ; sa capacité est la même que sa longueur, qui est la même que son nombre.
Une limite inférieure cohérente
La limite inférieure d’une collection est l’index de son premier élément. Toutes les collections indexées dans les System.Collections espaces de noms ont une limite inférieure de zéro, ce qui signifie qu’elles sont indexées à 0. Array a une limite inférieure de zéro par défaut, mais une limite inférieure différente peut être définie lors de la création d’une instance de la classe Array à l’aide Array.CreateInstancede .
Synchronisation pour l’accès à partir de plusieurs threads (System.Collections classes uniquement).
Les types de collections non génériques de l’espace de noms System.Collections fournissent une certaine cohérence de thread pour la synchronisation, généralement exposée par des membres SyncRoot et IsSynchronized. Ces collections ne sont pas thread-safe par défaut. Si vous avez besoin d'un accès multithread évolutif et efficace pour une collection, utilisez l'une des classes de l'espace de noms System.Collections.Concurrent ou envisagez d'utiliser une collection immuable. Pour plus d’informations, consultez Thread-Safe Collections.
Choisir une collection
En général, vous devez utiliser des collections génériques. Le tableau suivant décrit certains scénarios de collection courants et les classes de collection que vous pouvez utiliser pour ces scénarios. Si vous débutez avec les collections génériques, le tableau suivant vous aidera à choisir la collection générique qui convient le mieux à votre tâche :
| Je veux... | Options de collection génériques | Options de collection non générique | Options de collection thread-safe ou immuable |
|---|---|---|---|
| Stocker des éléments en tant que paires clé/valeur pour rechercher rapidement par clé | Dictionary<TKey,TValue> | Hashtable (Collection de paires clé/valeur organisées en fonction du code de hachage de la clé.) |
ConcurrentDictionary<TKey,TValue> ReadOnlyDictionary<TKey,TValue> ImmutableDictionary<TKey,TValue> |
| Accéder aux éléments par index | List<T> | Array ArrayList |
ImmutableList<T> ImmutableArray |
| Utiliser des éléments premier entré, premier sorti (FIFO) | Queue<T> | Queue | ConcurrentQueue<T> ImmutableQueue<T> |
| Utiliser des données dernier entré, premier sorti (LIFO) | Stack<T> | Stack | ConcurrentStack<T> ImmutableStack<T> |
| Accéder aux éléments de manière séquentielle | LinkedList<T> | Aucune recommandation | Aucune recommandation |
| Recevoir des notifications lorsque des éléments sont supprimés ou ajoutés à la collection. (implémente INotifyPropertyChanged et INotifyCollectionChanged) | ObservableCollection<T> | Aucune recommandation | Aucune recommandation |
| Collection triée | SortedList<TKey,TValue> | SortedList | ImmutableSortedDictionary<TKey,TValue> ImmutableSortedSet<T> |
| Ensemble de fonctions mathématiques | HashSet<T> SortedSet<T> |
Aucune recommandation | ImmutableHashSet<T> ImmutableSortedSet<T> |
Complexité algorithmique des collections
Lorsque vous choisissez une classe de collection, il vaut la peine d’envisager des compromis potentiels en termes de performances. Utilisez le tableau suivant pour référencer la comparaison des différents types de collections mutables en complexité algorithmique à leurs équivalents immuables correspondants. Souvent, les types de collection immuables sont moins performants, mais offrent une immuabilité, ce qui est souvent un avantage comparatif valide.
| Mutable | Coût amorti | Pire cas | Immuable | Complexité |
|---|---|---|---|---|
Stack<T>.Push |
O(1) | O(n) |
ImmutableStack<T>.Push |
O(1) |
Queue<T>.Enqueue |
O(1) | O(n) |
ImmutableQueue<T>.Enqueue |
O(1) |
List<T>.Add |
O(1) | O(n) |
ImmutableList<T>.Add |
O(log n) |
List<T>.Item[Int32] |
O(1) | O(1) | ImmutableList<T>.Item[Int32] |
O(log n) |
List<T>.Enumerator |
O(n) |
O(n) |
ImmutableList<T>.Enumerator |
O(n) |
HashSet<T>.AddRecherche |
O(1) | O(n) |
ImmutableHashSet<T>.Add |
O(log n) |
SortedSet<T>.Add |
O(log n) |
O(n) |
ImmutableSortedSet<T>.Add |
O(log n) |
Dictionary<T>.Add |
O(1) | O(n) |
ImmutableDictionary<T>.Add |
O(log n) |
Dictionary<T> Recherche |
O(1) | O(1) – ou strictement O(n) |
ImmutableDictionary<T> Recherche |
O(log n) |
SortedDictionary<T>.Add |
O(log n) |
O(n journal n) |
ImmutableSortedDictionary<T>.Add |
O(log n) |
Un List<T> peut être énuméré efficacement à l’aide d’une for boucle ou d’une foreach boucle. Toutefois, un ImmutableList<T> effectue un travail médiocre à l'intérieur d'une boucle for, en raison du temps O(log n) requis par son indexeur. Énumérer un ImmutableList<T> à l'aide d'une boucle foreach est efficace, car ImmutableList<T> utilise un arbre binaire pour stocker ses données au lieu d'un tableau, comme List<T>. Un tableau peut être rapidement indexé, tandis qu’une arborescence binaire doit être parcourue jusqu’à ce que le nœud avec l’index souhaité soit trouvé.
En outre, la complexité de SortedSet<T> est identique à celle de ImmutableSortedSet<T> puisqu'ils utilisent tous deux des arborescences binaires. La différence significative est que ImmutableSortedSet<T> utilise une arborescence binaire immuable. Comme ImmutableSortedSet<T> propose également une classe System.Collections.Immutable.ImmutableSortedSet<T>.Builder qui permet une modification, vous pouvez avoir à la fois l'immuabilité et les performances.
Articles connexes
| Titre | Descriptif |
|---|---|
| Sélection d’une classe de collection | Décrit les différentes collections et vous aide à en sélectionner un pour votre scénario. |
| Types de collection couramment utilisés | Décrit les types de collection génériques et non génériques couramment utilisés, tels que System.Array, System.Collections.Generic.List<T>et System.Collections.Generic.Dictionary<TKey,TValue>. |
| Quand utiliser des collections génériques | Décrit l’utilisation des types de collection génériques. |
| Comparaisons et tris dans les collections | Décrit l’utilisation des comparaisons d’égalité et des comparaisons de tri dans les collections. |
| Types de collection triés | Décrit les performances et les caractéristiques des collections triées. |
| Types de collections Hashtable et Dictionary | Décrit les fonctionnalités des types de dictionnaires génériques et non génériques basés sur le hachage. |
| Collections thread-safe | Décrit les types de collection tels que System.Collections.Concurrent.BlockingCollection<T> et System.Collections.Concurrent.ConcurrentBag<T> qui prennent en charge l’accès simultané sécurisé et efficace à partir de plusieurs threads. |
| System.Collections.Immutable | Présente les collections immuables et fournit des liens vers les types de collection. |