103 votes

Dans quel ordre les a C# pour chaque boucle d'itérer sur une Liste<T>?

Je me demandais à propos de l'ordre d'une boucle foreach en C# boucle par le biais d'un System.Collections.Generic.List<T> objet.

J'ai trouvé une autre question sur le même sujet, mais je ne pense pas qu'il répond à ma question à ma satisfaction.

Quelqu'un qui affirme qu'aucun ordre est défini. Mais que quelqu'un d'autre membres, l'ordre qu'il parcourt un tableau est fixe (de 0 à Length-1). 8.8.4 L'instruction foreach

Il a également été dit que la situation est la même pour toutes les classes standard avec une commande (par exemple, List<T>). Je ne peux trouver aucune documentation à l'arrière de ça. Donc, pour tout ce que je sais que ça peut fonctionner comme ça maintenant, mais peut-être dans la prochaine .Version NET, il sera différent (même si c'est peu probable).

J'ai également regardé l' List(t).Enumerator de la documentation, mais sans succès.

Une autre question concernant les états que pour Java, il est spécifiquement mentionné dans la documentation:

List.iterator()renvoie un itérateur sur les éléments de cette liste dans une séquence appropriée."

Je suis à la recherche de quelque chose comme ça dans le C# de la documentation.

Merci à l'avance.

Edit: Merci à vous tous pour toutes vos réponses (incroyable à quelle vitesse j'ai eu tellement de réponses). Ce que je comprends de toutes les réponses, c'est que List<T> n'a toujours itérer dans l'ordre de son indexation. Mais j'aimerais voir un clair de la paix de la documentation disant cela, semblable à la documentation de Java sur List.

117voto

Jon Skeet Points 692016

Fondamentalement, il est à l' IEnumerator mise en œuvre - mais pour un List<T> il ira toujours dans l'ordre naturel de la liste, c'est à dire du même ordre que l'indexeur: list[0], list[1], list[2] etc.

Je ne crois pas que c'est explicitement documentées - au moins, je n'ai pas trouvé de documentation - mais je pense que vous pouvez le traiter comme garantie. Toute modification de la commande serait inutilement briser tous les types de code. En fait, je serais surpris de voir la mise en œuvre d' IList<T> qui ont désobéi à présent. Certes, il serait agréable de le voir plus précisément documentées...

9voto

RvdK Points 10793

Dans votre lien, a accepté de répondre à états dans la Spécification du Langage C# Version 3.0, page 240:

L'ordre dans lequel foreach parcourt les éléments d'un tableau, est que suit: unique dimensions des tableaux les éléments sont parcourus dans l'augmentation de l'indice de l'ordre, en commençant par l'index 0 et se terminant à l'indice de Longueur – 1. Pour multi-dimensions des tableaux, des éléments sont traversée tels que les indices de la dimension la plus à droite sont augmentés tout d'abord, puis la prochaine à gauche, dimension, et ainsi de suite à gauche. La suite exemple imprime chaque valeur dans une tableau à deux dimensions, dans l'élément ordre:

using System;
class Test
{
  static void Main() {
  	double[,] values = {
  		{1.2, 2.3, 3.4, 4.5},
  		{5.6, 6.7, 7.8, 8.9}
  	};
  	foreach (double elementValue in values)
  		Console.Write("{0} ", elementValue);
  	Console.WriteLine();
  }
}

La sortie produite est comme suit: 1.2 2.3 3.4 4.5 5.6 6.7 7.8 8.9 Dans l'exemple

int[] numbers = { 1, 3, 5, 7, 9 };
foreach (var n in numbers) Console.WriteLine(n);
the type of n is inferred to be int, the element type of numbers.

4voto

Brendan Enrick Points 2892

L'ordre est défini par l'itérateur être utilisée pour parcourir une collection de données à l'aide d'une boucle foreach.

Si vous êtes en utilisant une norme collection de plaquettes indexables (comme une Liste), puis il va parcourir la collection en commençant par l'index 0 et le déplacement.

Si vous avez besoin de la commande, vous pouvez contrôler la façon dont l'itération de la collecte est assurée par la mise en œuvre de votre propre IEnumerable, ou vous pouvez trier la liste de la façon dont vous le souhaitez avant l'exécution de la boucle foreach.

C'est ce qui explique comment Énumérateur de travaux pour la Liste générique. Au premier abord, l'élément courant est défini et utilise MoveNext pour se rendre à l'élément suivant.

Si vous lisez MoveNext , il indique qu'il va commencer avec le premier élément de la collection, et à partir de là, passer à la suivante jusqu'à ce qu'il atteigne la fin de la collecte.

2voto

KillJoy Points 9

J'ai juste eu à faire quelque chose de similaire comme un petit hack de code, mais il ne fonctionne pas pour ce que j'essayais de faire n'réorganiser la liste pour moi.

L'utilisation de LINQ pour modifier l'ordre

         DataGridViewColumn[] gridColumns = new DataGridViewColumn[dataGridView1.Columns.Count];
         dataGridView1.Columns.CopyTo(gridColumns, 0); //This created a list of columns

         gridColumns = (from n in gridColumns
                        orderby n.DisplayIndex descending
                        select n).ToArray(); //This then changed the order based on the displayindex

1voto

Broam Points 2646

Les listes semblent retourner les articles dans un ordre, ils sont dans le magasin de sauvegarde--donc, si ils sont ajoutés à la liste de cette façon, ils vont être renvoyée de cette façon.

Si votre programme dépend de la commande, vous pouvez les trier avant la traversée de la liste.

C'est un peu ridicule pour un linéaire de la recherche: mais si vous avez besoin de l'ordre d'une certaine façon, votre meilleur pari est de faire des articles de cette commande.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X