Je sais que je pourrais utiliser pour la déclaration et obtenir le même effet, mais ce que je veux savoir, c'est, puis-je la boucle vers l'arrière par une boucle foreach en C#?
Réponses
Trop de publicités?Si vous êtes sur .Net 3.5, vous pouvez faire ceci:
IEnumerable<int> enumerableThing = ...;
foreach (var x in enumerableThing.Reverse())
Il n'est pas très efficace, car il a essentiellement passer par l'agent recenseur transmet de tout mettre sur une pile apparaît à tout remettre dans l'ordre inverse.
Si vous avez un directement-indexables collection (par exemple, IList), vous devez absolument utiliser une boucle for à la place.
Si vous êtes sur .Net 2.0 et ne peut pas utiliser une boucle for (c'est à dire vous avez juste un IEnumerable), alors vous n'avez qu'à écrire votre propre fonction d'inversion, cela devrait fonctionner:
static IEnumerable<T> Reverse<T>(IEnumerable<T> input)
{
return new Stack<T>(input);
}
Cela repose sur un comportement qui n'est peut être pas évident. Lorsque vous passez un IEnumerable de la pile constructeur qu'il va itérer dessus et poussez les éléments sur la pile. Lorsque vous parcourir par le biais de la pile, il apparaît les choses dans l'ordre inverse.
Cette et la .Net 3.5 Reverse()
méthode d'extension sera bien évidemment exploser si vous la donnez un IEnumerable qui ne cesse jamais de retour des articles.
Lorsque l'on travaille avec une liste (indexation directe), vous ne pouvez pas le faire de manière aussi efficace que l'utilisation d'un for
boucle.
Edit: ce Qui signifie généralement, lorsque vous êtes en mesure d'utiliser un for
boucle, il est probable que la méthode appropriée pour cette tâche. De Plus, pour autant qu' foreach
est mis en œuvre dans l'ordre, le concept lui-même est construit pour exprimer des boucles qui sont indépendants de l'élément d'index et de l'itération de l'ordre, ce qui est particulièrement important dans la programmation parallèle. Il est de mon avis que l'itération en s'appuyant sur ordonnance ne devrait pas utiliser foreach
pour le bouclage.
Comme 280Z28 dit, pour un IList<T>
vous pouvez simplement utiliser l'index. Vous pouvez le cacher dans une méthode d'extension:
public static IEnumerable<T> FastReverse<T>(this IList<T> items)
{
for (int i = items.Count-1; i >= 0; i--)
{
yield return items[i];
}
}
Ce sera plus rapide que Enumerable.Reverse()
qui les tampons de toutes les données de la première. (Je ne crois pas qu' Reverse
a toutes les optimisations appliquées dans la façon dont Count()
.) Notez que cette mise en mémoire tampon signifie que les données sont lues complètement lors du premier démarrage de l'itération, alors qu' FastReverse
va "voir" toutes les modifications apportées à la liste alors que vous parcourez. (Il sera également se briser si vous supprimez plusieurs éléments entre les itérations.)
Pour le général séquences, il n'y a aucun moyen d'itération inverse - la séquence pourrait être infinie, par exemple:
public static IEnumerable<T> GetStringsOfIncreasingSize()
{
string ret = "";
while (true)
{
yield return ret;
ret = ret + "x";
}
}
Que voulez-vous attendre si vous avez essayé d'effectuer une itération sur que dans le sens inverse?
Si vous utilisez une Liste, vous pouvez également utiliser ce Code:
List<string> list = new List<string>();
list.Add("1");
list.Add("2");
list.Add("3");
list.Reverse();
C'est une methode que d'écrire la liste inverse est en elle-même.
Maintenant, le foreach:
foreach(string s in list)
{
Console.WriteLine(s);
}
La sortie est:
3
2
1