1.5. foreach tableaux et collections
Plan général:
...........
1. Les collections
1.1 Les composants en général
1.2 Les contrôles sur un formulaire
1.3 Influence de la propriété parent sur l'affichage visuel d'un contrôle
1.4 Des graphiques dans les formulaires avec le GDI+
1.5 Le dessin doit être persistant
1.6 Deux exemples de graphiques sur plusieurs contrôles
- méthode générale pour tout redessiner
- des dessins sur événements spécifiques
1. foreach
L'instruction foreach répète un groupe d'instructions incorporées
pour chaque élément d'un tableau ou d'une collection. L'instruction
foreach sert à itérer la collection pour obtenir les informations
souhaitées, mais ne doit pas être utilisée pour modifier
le contenu de la collection afin d'éviter les effets collatéraux
imprévisibles. L'instruction prend la forme suivante :
foreach (type identifier in expression) statement
1. Les collections
Les données étroitement liées peuvent être gérées
plus efficacement quand elles sont regroupées pour former une collection.
Au lieu d'écrire un code distinct pour gérer chaque objet,
vous pouvez utiliser le même code pour traiter tous les éléments
d'une collection.
Pour manager une collection, vous pouvez utiliser la classe Array ou les classes System.Collections
pour ajouter, supprimer et modifier des éléments individuels
d'une collection ou une série d'éléments. Vous pouvez
même copier une collection complète dans une autre collection.
1.1 les collections en général
Une collection est un ensemble d'objets du même type qui sont regroupés ensemble.
Les objets d'un type quelconque peuvent être regroupés en une
collection du type Object afin de tirer parti des constructions inhérentes
au langage. Par exemple, l'instruction C# foreach s'attend à
ce que tous les objets de la collection soient du même type.
Toutes les collections qui implémentent directement ou indirectement
l'interface ICollection partagent plusieurs fonctionnalités en plus
des méthodes qui ajoutent, suppriment ou recherchent des éléments
:
Un énumérateur. Un énumérateur est un objet qui
effectue une itération sur la collection qui lui est associée.
Il peut être considéré comme un pointeur mobile vers
un élément quelconque de la collection. Un énumérateur
ne peut être associé qu'à une seule collection, mais
une collection peut avoir plusieurs énumérateurs. L'instruction
C# foreach (for each dans Visual Basic) utilise l'énumérateur
et masque la complexité de manipulation de celui-ci.
Membres de la synchronisation. La synchronisation garantit la sécurité
des threads lors de l'accès à des éléments de
la collection. Par défaut, les collections ne sont pas thread-safe.
Seules quelques classes de l'espace de noms Collections fournissent une méthode
Synchronize qui crée un wrapper thread-safe par-dessus la collection.
Cependant, toutes les classes de l'espace de noms Collections fournissent
une propriété SyncRoot que des classes dérivées
peuvent utiliser pour créer leur propre wrapper thread-safe. Une propriété
IsSynchronized est également fournie pour déterminer si la
collection est thread-safe.
La méthode CopyTo. Toutes les collections peuvent être copiées
dans un tableau à l'aide de la méthode CopyTo ; cependant,
l'ordre des éléments dans le nouveau tableau est déterminé
par 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.
Les classes Collections sont généralement réparties en trois catégories :
Collections génériques. Il s'agit des variations communes des
collections de données, telles que les tables de hachage, les files
d'attente, les piles, les dictionnaires et les listes.
Collections binaires. Il s'agit de collections dont les éléments
sont des bits indicateurs. Leur comportement est un peu différent
de celui des autres collections.
Collections spécialisées. Ces collections répondent
à des objectifs hautement spécifiques ; il s'agit généralement
de gérer un élément de type spécifique, comme
StringDictionary.
Veillez à choisir votre classe de collection avec beaucoup de soin.
Si chaque collection a sa propre fonctionnalité, elle a également
ses propres limites. Plus une collection est spécialisée, plus
elle est limitée.
Veillez à choisir votre classe Collections avec beaucoup de soin.
Le choix d'une collection erronée peut limiter l'usage que vous pouvez
en faire.
Réfléchissez aux questions suivantes :
Avez-vous besoin d'une liste séquentielle dans laquelle l'élément
est généralement abandonné une fois sa valeur extraite
?
Si la réponse est positive, pensez à Queue ou à Stack.
Si la réponse est négative, songez aux autres collections.
Avez-vous besoin d'accéder aux éléments dans un certain
ordre, par exemple premier entré premier sorti, dernier entré
premier sorti ou un ordre aléatoire ?
Queue offre un accès de type premier entré premier sorti.
Stack offre un accès de type dernier entré premier sorti.
Les autres collections offrent un accès aléatoire.
Avez-vous besoin d'accéder à chaque élément par son index ?
ArrayList et StringCollection offrent l'accès à leurs éléments
par l'index de base zéro de l'élément.
Hashtable, SortedList, ListDictionary et StringDictionary offrent l'accès
à leurs éléments par la clé de l'élément.
NameObjectCollectionBase et NameValueCollection offrent l'accès à
leurs éléments par l'index de base zéro ou la clé
de l'élément.
Chaque élément contiendra-t-il une seule valeur, une combinaison
d'une clé et d'une valeur ou une combinaison d'une clé et de
plusieurs valeurs ?
Une seule valeur : utilisez l'une des collections reposant surIList.
Une clé et une valeur : utilisez l'une des collections reposant sur IDictionary.
Une clé et plusieurs valeurs : utilisez la classe NameValueCollection
de l'espace de noms System.Collections.Specialized.
Avez-vous besoin de trier les éléments dans un ordre différent
de celui dans lequel ils ont été entrés ?
Hashtable trie les éléments selon le code de hachage de la clé.
SortedList trie les éléments par clé, sur la base d'une implémentation IComparer.
ArrayList fournit une méthode Sort qui accepte l'implémentation IComparer en tant que paramètre.
Avez-vous besoin d'opérations de recherche et d'extraction d'informations rapides ?
ListDictionary est plus rapide que Hashtable pour les petites collections (10 éléments ou moins).
Avez besoin de collections qui acceptent uniquement des chaînes ?
StringCollection (fondée sur IList) et StringDictionary (fondée
sur IDictionary) font partie de l'espace de noms System.Collections.Specialized.
1.2 les contrôles sur un formulaire
L'ajout
(et la suppression) de contrôles dans un contrôle conteneur de
vos formulaires (comme le contrôle Panel ou GroupBox, voire le formulaire
lui-même) représente une tâche courante du développent
d'applications. Ces contrôles gèrent une collection Controls,
qui assure le suivi des contrôles qui y sont placés.
public Control.ControlCollection Controls {get;}
Représente une collection d'objets Control.
Les méthodes Add, Remove et RemoveAt permettent d'ajouter et de supprimer
des contrôles individuels de la collection. Vous pouvez également
utiliser les méthodes AddRange ou Clear pour ajouter ou supprimer
tous les contrôles de la collection.
Vous pouvez déterminer si Control est un membre de la collection en
passant le contrôle dans la méthode Contains. Pour obtenir la
valeur d'index de l'emplacement de Control dans la collection, passez le
contrôle dans la méthode IndexOf. La collection peut être
copiée dans un tableau en appelant la méthode CopyTo.
panel1.Controls.Add(newPanelButton);
panel1.Controls.Remove(newPanelButton);
newPanelButton.Dispose();
1.3 les hashtable
Représente une collection de paires valeur-clé qui sont organisées
en fonction du code de hachage de la clé.
Chaque élément est une paire valeur-clé stockée
dans un objet DictionaryEntry. Une clé ne peut pas être une
référence null (Nothing dans Visual Basic), contrairement à
une valeur.
Les objets utilisés comme clés dans Hashtable doivent implémenter
ou hériter des méthodes Object.GetHashCode et Object.Equals.
Si l'égalité des clés est simplement une égalité
des références, l'implémentation de ces méthodes
héritée suffit. De plus, ces méthodes doivent donner
les mêmes résultats lorsqu'elles sont appelées avec les
mêmes paramètres si la clé existe dans Hashtable. Les
objets de clé doivent être immuables tant qu'ils sont utilisés
comme clés dans Hashtable.
Quand un élément est ajouté à Hashtable, il est
placé dans un compartiment basé sur le code de hachage de la
clé. Les recherches suivantes de la clé utiliseront le code
de hachage de cette clé pour ne rechercher que dans un compartiment
précis, ce qui réduira substantiellement le nombre de comparaisons
de clés nécessaire pour trouver un élément.
Le facteur de charge de Hashtable détermine le ratio maximal d’éléments
par compartiment. Des facteurs de charge plus petits écourtent les
temps moyens de recherche, mais augmentent la consommation de mémoire.
Le facteur de charge par défaut est de 1, ce qui représente
généralement le meilleur compromis entre la vitesse et la taille.
Un facteur de charge différent peut être spécifié
si Hashtable est créé.
Lorsque des éléments sont ajoutés à Hashtable,
le facteur de charge réel de Hashtable augmente. Lorsque le facteur
de charge réel devient égal au facteur de charge, le nombre
de compartiments dans Hashtable est automatiquement augmenté au plus
petit nombre premier supérieur à deux fois le nombre actuel
de compartiments de Hashtable.
Chaque objet de clé dans Hashtable doit apporter sa propre fonction
de hachage, qui est accessible en appelant GetHash. Cependant, tout objet
implémentant IHashCodeProvider peut être passé à
un constructeur de Hashtable et cette fonction de hachage est utilisée
pour tous les objets de la table.