Maison  >  Article  >  développement back-end  >  Explication détaillée du code graphique des types de collections C#

Explication détaillée du code graphique des types de collections C#

黄舟
黄舟original
2017-03-09 15:23:191996parcourir

Collections en C#

Les collections sont une partie importante de .NET FCL (Framework Class Library) et l'une des fonctions les plus couramment utilisées dans notre développement. Elles sont presque partout. Comme le dit le proverbe, sachez ce que c'est et pourquoi. Lorsque vous voyez IEnumerable, IEnumerator et ICollection, connaissez-vous les différences entre eux ? En plus de List et Dictionary, quelles autres classes de collection avez-vous utilisées ? Sans plus tarder, nous examinerons aujourd'hui certaines des interfaces qui définissent les classes de collection et leurs implémentations.

Interface de collecte

Jetons d'abord un coup d'œil aux interfaces que FCL nous propose :

IEnumerable et IEnumberator

public interface IEnumerator
{
 
    bool MoveNext();
    object Current {  get; }
    void Reset();
}

IEnumerator définit la méthode de base qui nous permet de parcourir la collection afin que nous puissions obtenir un accès unidirectionnel à chaque élément de la collection. IEnumerable n'a qu'une seule méthode, GetEnumerator, qui est le traverseur.

public interface IEnumerable
{
    IEnumerator GetEnumerator();
}

Remarque : Le foreach que nous utilisons souvent est une sorte de sucre syntaxique. Il appelle en fait la fonction de traversée implémentée par Current et MoveNext dans Enumerator.

List<string> list = new List<string>() 
{ 
    "Jesse",
    "Chloe",
    "Lei",
    "Jim",
    "XiaoJun"
};
 
// Iterate the list by using foreach
foreach (var buddy in list)
{
    Console.WriteLine(buddy);
}
 
// Iterate the list by using enumerator
List<string>.Enumerator enumerator = list.GetEnumerator();
while (enumerator.MoveNext())
{
    Console.WriteLine(enumerator.Current);
}

Le foreach et l'énumérateur utilisés dans le code ci-dessus seront éventuellement traduits en MoveNext et Current in IL de l'énumérateur.

IEnumerable est une interface très utile. Les avantages de sa mise en œuvre incluent :

  1. . Prise en charge de chaque déclaration


  2. Interagissez avec d'autres bibliothèques en tant que classe de collection standard


  3. Répondre aux besoins des interfaces de collecte plus complexes


  4. Initialiseur de collecte de support

Bien entendu, il existe de nombreuses façons d'y parvenir, comme suit :

  1. Si notre collection vient en encapsulant d'autres classes de collection, alors nous pouvons renvoyer directement l'énumérateur de cette collection


  2. Utilisez le retour de rendement pour revenir


  3. Implémentez notre propre IEnumerator pour implémenter

Ici, je vais vous montrer comment renvoyer l'enquêteur

public class BuddyList : IEnumerable
{
    private string[] data= new string[]
    { 
        "Jesse",
        "Chloe",
        "Lei",
        "Jim",
        "XiaoJun"
    };
 
    public IEnumerator GetEnumerator()
    {
        foreach (var str in data)
        {
            yield return str;
        }
    }
}
 
var myBuddies= new BuddyList();
foreach (var str in myBuddies)
{
    Console.WriteLine(str);
}

via le rendement ICollection8742468051c85b06f0a0af9e3e506b5c et ICollection

Dès la première image en haut, nous pouvons savoir qu'ICollection est directement héritée de IEnumerable. En fait, c'est également le cas. Nous pouvons dire qu'ICollection prend en charge plus de fonctions que IEnumerable, fournissant non seulement des fonctions de traversée de base, mais incluant également :

  1. . Comptez le nombre d'ensembles et d'éléments


  2. Récupérer l'indice de l'élément


  3. Déterminer si


  4. Ajouter des éléments à la fin


  5. Supprimez des éléments et ainsi de suite. . .

ICollection est légèrement différent de ICollection8742468051c85b06f0a0af9e3e506b5c. ICollection ne fournit pas les fonctions d'édition de collections, à savoir Ajouter et Supprimer. Y compris la vérification si l'élément contient n'est pas pris en charge.

​IList8742468051c85b06f0a0af9e3e506b5c et IList

IList hérite directement de ICollection et IEnumerable. Il inclut donc les fonctionnalités des deux et prend en charge l'accès et l'ajout d'éléments basés sur des indices. IndexOf, Insert, RemoveAt et ainsi de suite. On peut dire que IEnumerable prend en charge le moins de fonctions, uniquement le parcours. ICollection prend en charge un peu plus de fonctions, notamment le parcours mais également la maintenance de la collection. Et IList est la version la plus complète.

IReadOnlyList8742468051c85b06f0a0af9e3e506b5c

Il s'agit d'un nouveau type d'interface dans Framework 4.5. Il peut être considéré comme une version abrégée de IList8742468051c85b06f0a0af9e3e506b5c, supprimant toutes les fonctions susceptibles de modifier cette collection. Par exemple : Ajouter, SupprimerAt, etc.

IDictionary8c189faf63255a5ea96468ba21dd0564

IDictionary donne accès à une collection de paires clé-valeur. Il hérite également de ICollection8742468051c85b06f0a0af9e3e506b5c et étend la méthode d'accès et d'exploitation des données via Key.

Classe de collection générique associative

La classe de collection associative est ce que nous appelons souvent une collection de paires clé-valeur, nous permettant d'accéder et de maintenir la collection via Key. Jetons d'abord un coup d'œil à ce que les classes de collection associatives génériques FCL nous proposent :

  1. Dictionnaire8c189faf63255a5ea96468ba21dd0564


  2. SortedDictionary8c189faf63255a5ea96468ba21dd0564


  3. SortedList8c189faf63255a5ea96468ba21dd0564

Dictionnaire8c189faf63255a5ea96468ba21dd0564

Dictionary8c189faf63255a5ea96468ba21dd0564 est probablement notre collection associative la plus couramment utilisée. Le temps nécessaire pour accéder, ajouter et supprimer des données est le plus rapide parmi toutes les classes de collection, car elle utilise Hashtable en interne comme structure de stockage, donc peu importe. combien de paires clé-valeur sont stockées, le temps nécessaire pour interroger/ajouter/supprimer est le même et sa complexité temporelle est O(1).

Dictionnaire8c189faf63255a5ea96468ba21dd0564L'avantage est qu'il est rapide à rechercher et à insérer, alors quels sont ses inconvénients ? Étant donné que Hashtable est utilisé comme structure de stockage, cela signifie que les données à l'intérieur sont disposées dans le désordre, il faut donc un petit effort pour parcourir les données dans Dictionaryb6842da76bed01162354d37c4f2d3464

Le type comme TKey doit implémenter GetHashCode() et Equals() ou fournir un IEqualityComparer, sinon fonctionner Des problèmes peuvent survenir.

SortedDictioanry8c189faf63255a5ea96468ba21dd0564

SortedDictionary8c189faf63255a5ea96468ba21dd0564 et Dictionary8c189faf63255a5ea96468ba21dd0564 sont à peu près similaires, mais il existe une légère différence dans l'implémentation. SortedDictionary8c189faf63255a5ea96468ba21dd0564 utilise une arborescence binaire comme structure de stockage. Et disposés dans l'ordre des clés. Dans ce cas, le TKey de SortedDictionary8c189faf63255a5ea96468ba21dd0564 doit implémenter IComparable7c013bef549e108856916cfbe0707d60. Si vous souhaitez interroger rapidement et bien prendre en charge le tri, utilisez SortedDictionary.

SortedList8c189faf63255a5ea96468ba21dd0564                                                           SortedList8c189faf63255a5ea96468ba21dd0564 est une autre collection associative qui prend en charge le tri. Mais la différence est que SortedList stocke les données dans un tableau. C'est-à-dire que les opérations d'ajout et de suppression sont linéaires et que la complexité temporelle est O(n), car l'opération des éléments peut entraîner le déplacement de toutes les données. Mais comme la recherche binaire est utilisée pendant la recherche, les performances de recherche seront meilleures et la complexité temporelle est O(log n). Par conséquent, le scénario d'utilisation recommandé est le suivant : si vous souhaitez effectuer une recherche rapide et que vous souhaitez que la collection soit organisée par ordre de clés et que les opérations de collecte (ajout et suppression) soient relativement peu nombreuses, il s'agit de SortedList.

Classe de collection générique non associative

Les collections non associatives sont des classes de collection qui ne nécessitent pas d'opérations clés. Nous pouvons généralement utiliser les éléments eux-mêmes ou les indices pour fonctionner. FCL nous fournit principalement les classes de collections génériques non associatives suivantes.

    Liste8742468051c85b06f0a0af9e3e506b5c

  1. LinkedList8742468051c85b06f0a0af9e3e506b5c

  2. HashSet8742468051c85b06f0a0af9e3e506b5c

  3. SortedSet8742468051c85b06f0a0af9e3e506b5c

  4. Pile8742468051c85b06f0a0af9e3e506b5c

  5. File d'attente8742468051c85b06f0a0af9e3e506b5c
  6. Liste8742468051c85b06f0a0af9e3e506b5c

La classe générique List fournit un type de collection sans limite de longueur. List maintient en interne un tableau d'une certaine longueur (la longueur initiale par défaut est 4). Lorsque la longueur de l'élément inséré dépasse 4 ou la longueur initiale, il sera réinitialisé. -créé.Nouveau tableau, la longueur de ce nouveau tableau est 2 fois la longueur initiale (pas toujours 2 fois, quand on constate qu'il continue de s'étendre, le multiple deviendra plus grand), puis copiez le tableau d'origine. Ainsi, si nous savons combien d'éléments nous allons utiliser cette collection pour contenir, nous pouvons spécifier la valeur initiale lors de sa création, évitant ainsi de créer à plusieurs reprises de nouveaux tableaux et de copier des valeurs.

De plus, comme l'essence interne est un tableau, l'ajout de données à la liste n'est peut-être pas plus rapide, mais l'ajout ou la suppression de données en tête ou au milieu des données est relativement moins efficace car cela affectera le réarrangement d'autres données.

LinkedList8742468051c85b06f0a0af9e3e506b5c

LinkedList maintient une liste chaînée bidirectionnelle en interne, ce qui signifie que les performances d'ajout ou de suppression de données n'importe où dans LinkedList sont très rapides. Parce que cela ne fait pas bouger les autres éléments. Dans des circonstances normales, List nous suffit, mais si les opérations d'ajout et de suppression au milieu de cette collection sont très fréquentes, il est recommandé d'utiliser LinkedList.

HashSet8742468051c85b06f0a0af9e3e506b5c

HashSet est un ensemble non ordonné qui peut conserver son unicité. Nous pouvons également considérer HashSet comme Dictionary8c189faf63255a5ea96468ba21dd0564, sauf que TKey et TValue pointent vers le même objet. HashSet est très approprié lorsque nous devons garder les éléments de l'ensemble uniques mais n'avons pas besoin d'être disposés dans l'ordre.

HashSet ne prend pas en charge l'accès aux indices.

SortedSet8742468051c85b06f0a0af9e3e506b5c

SortedSet et HashSet sont comme SortedDictionary et Dictionary. Vous souvenez-vous encore de la différence entre les deux ? SortedSet est également un arbre binaire en interne, utilisé pour prendre en charge l'organisation des éléments dans l'ordre.

Pile8742468051c85b06f0a0af9e3e506b5c

File d'attente Dernier entré, premier sorti

L'accès par indice n'est pas pris en charge

​Queu8742468051c85b06f0a0af9e3e506b5c

File d'attente premier entré, premier sorti
​Ne prend pas en charge l'accès à

en appuyant sur l'indice Scénarios d'utilisation recommandés

Rassembler

Organiser dans l'ordre

Stockage Lianshun

Méthode d'accès direct

Heure de la visite

Temps de fonctionnement

Remarques

Dictionnaire

Oui

Clé

Clé :

O(1)

O(1)

Les performances d'accès les plus rapides et ne prennent pas en charge le tri

TriéDictionnaire

Organiser dans l'ordre

Non

Clé

Clé :
O(log n)

O(log n)

Un compromis entre accès rapide et prise en charge du tri

Liste triée

Organiser dans l'ordre

Oui

Clé

Clé :

O(log n)

O(n)

Semblable à SortedDictionary, sauf que les données sont utilisées en interne au lieu de l'arborescence comme structure de stockage.

Liste

Les utilisateurs peuvent contrôler avec précision la position des éléments

Oui

Indice

Indice : O(1)

Valeur : O(n)

O(n)

Idéal pour les petites collections qui nécessitent un accès direct à chaque élément.

Liste liée

Les utilisateurs peuvent contrôler avec précision la position des éléments

Non

Non pris en charge

Valeur :

O(n)

O(1)

Idéal pour les scénarios dans lesquels un accès direct à des éléments individuels n’est pas requis, mais des ajouts/suppressions très fréquents à la collection sont nécessaires.

HashSet

Non pris en charge

Oui

Clé

Clé :

O(1)

O(1)

Une collection qui préserve le caractère unique des éléments. Le tri n'est pas pris en charge

Ensemble trié

Organiser dans l'ordre

Non

Clé

Clé :

O(log n)

O(log n)

Peut conserver l’unicité des éléments et prendre en charge le tri.

Pile

LIFO

Oui

Seul l'élément supérieur peut être obtenu

Haut : O(1)

O(1)

File d'attente

FIFO

Oui

Seul l'élément du bas peut être obtenu

Recto : O(1)

O(1)

Collection de classes non génériques

La classe de collection générique est sortie dans .NET 2.0, ce qui signifie qu'il n'y avait rien de aussi pratique dans .NET 1.0. Désormais, fondamentalement, nous n'utilisons plus ces classes de collection, sauf lorsque nous effectuons des travaux pour maintenir la compatibilité avec l'ancien code. Jetons un coup d'œil aux classes de collection qui peuvent être utilisées par les programmeurs .NET à l'ère 1.0.

  1. ArraryList

Remplacé plus tard par List8742468051c85b06f0a0af9e3e506b5c.

  1. HashTable a ensuite été remplacé par Dictionary8c189faf63255a5ea96468ba21dd0564.


  2. La file d'attente a ensuite été remplacée par Queue8742468051c85b06f0a0af9e3e506b5c.


  3. SortedList a ensuite été remplacé par SortedList8742468051c85b06f0a0af9e3e506b5c.


  4. Stack a ensuite été remplacé par Stack8742468051c85b06f0a0af9e3e506b5c.

Classe de collecte Thread-safe

  1. ConcurrentQueue version thread-safe de Queue


  2. Version thread-safe ConcurrentStack de Stack


  3. Collection d'objets thread-safe ConcurrentBag


  4. Dictionnaire thread-safe ConcurrentDictionary


  5. BlocageCollection

Les classes de collection fournies par .NET sont l'une de nos classes d'outils les plus couramment utilisées. J'espère que cet article pourra aider tout le monde à mieux comprendre ces classes de collection. Bien sûr, je pense personnellement qu'il y a encore des imperfections. Par exemple, HashTable et Binary Search Tree ne sont pas étudiés en détail, et la comparaison entre les listes chaînées unidirectionnelles et les listes doublement chaînées n'est pas mentionnée dans cet article. Les amis intéressés peuvent en apprendre davantage.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn