Passer au contenu du pied de page
.NET AIDE

C# foreach avec index (Comment ça fonctionne pour les développeurs)

En C#, l'instruction foreach est généralement utilisée pour itérer sur des collections telles que des tableaux, des listes ou d'autres types énumérables. Cependant, une limitation est que la boucle foreach ne fournit pas une variable d'index intégrée pour suivre l'itération en cours. Les développeurs ont souvent besoin d'accéder à l'index de l'élément actuel. Ci-dessous, nous allons explorer diverses façons d'implémenter cette fonctionnalité et la bibliothèque IronPDF.

Les bases de la boucle foreach

La boucle foreach est conçue pour simplifier l'itération à travers des tableaux, des listes, des dictionnaires et d'autres types qui implémentent IEnumerable. Voici un exemple basique de l'utilisation d'une instruction foreach pour parcourir un tableau de type de données entiers :

int[] numbers = { 10, 20, 30, 40 };
foreach (int number in numbers)
{
    Console.WriteLine(number);
}
int[] numbers = { 10, 20, 30, 40 };
foreach (int number in numbers)
{
    Console.WriteLine(number);
}
Dim numbers() As Integer = { 10, 20, 30, 40 }
For Each number As Integer In numbers
	Console.WriteLine(number)
Next number
$vbLabelText   $csharpLabel

Dans cet exemple, le nombre représente l'élément de la collection à chaque itération. La boucle itère automatiquement à travers tous les éléments du tableau. Cependant, il n'y a pas de moyen intégré d'accéder à l'index actuel de l'élément.

Gestion de l'index dans une boucle foreach

Bien que C# ne fournisse pas directement l'index dans une boucle foreach, plusieurs techniques peuvent résoudre ce problème. Discutons de ces méthodes en détail.

Méthode 1 : Utilisation d'une variable distincte

L'une des manières les plus simples d'obtenir l'index de l'élément actuel est d'utiliser une variable d'index externe. Vous devrez l'incrémenter manuellement à l'intérieur de la boucle :

int[] numbers = { 10, 20, 30, 40 };
int numberIndex = 0;
foreach (int number in numbers)
{
    Console.WriteLine($"Index: {numberIndex}, Value: {number}");
    numberIndex++;
}
int[] numbers = { 10, 20, 30, 40 };
int numberIndex = 0;
foreach (int number in numbers)
{
    Console.WriteLine($"Index: {numberIndex}, Value: {number}");
    numberIndex++;
}
Dim numbers() As Integer = { 10, 20, 30, 40 }
Dim numberIndex As Integer = 0
For Each number As Integer In numbers
	Console.WriteLine($"Index: {numberIndex}, Value: {number}")
	numberIndex += 1
Next number
$vbLabelText   $csharpLabel

Dans ce code, la variable d'index est initialisée avant le début de la boucle puis incrémentée à l'intérieur de la boucle à chaque itération. Bien que cette approche fonctionne, elle nécessite de maintenir manuellement l'index, ce qui n'est pas toujours idéal.

Méthode 2 : Utilisation de la méthode Select de LINQ

La méthode Select de LINQ peut être utilisée pour projeter chaque élément d'une collection sous une nouvelle forme, y compris son index. Voici un exemple :

int[] numbers = { 10, 20, 30, 40 };
foreach (var item in numbers.Select((value, index) => new { value, index }))
{
    Console.WriteLine($"Index: {item.index}, Value: {item.value}");
}
int[] numbers = { 10, 20, 30, 40 };
foreach (var item in numbers.Select((value, index) => new { value, index }))
{
    Console.WriteLine($"Index: {item.index}, Value: {item.value}");
}
Dim numbers() As Integer = { 10, 20, 30, 40 }
For Each item In numbers.Select(Function(value, index) New With {
	Key value,
	Key index
})
	Console.WriteLine($"Index: {item.index}, Value: {item.value}")
Next item
$vbLabelText   $csharpLabel

Dans cet exemple, Select crée un objet anonyme contenant à la fois la valeur de l'élément actuel et son index. La boucle foreach peut alors itérer sur ces objets et accéder directement à la fois à l'index et à la valeur.

Méthode 3 : Utilisation d'un itérateur personnalisé

Vous pouvez implémenter une méthode d'extension d'itérateur personnalisée en utilisant le mot-clé yield return pour générer une méthode qui renvoie à la fois l'élément actuel et son index. C'est un peu plus avancé mais cela offre une solution flexible.

public static IEnumerable<(int index, T value)> WithIndex<T>(this IEnumerable<T> source)
{
    int index = 0;
    foreach (T value in source)
    {
        yield return (index, value);
        index++;
    }
}
public static IEnumerable<(int index, T value)> WithIndex<T>(this IEnumerable<T> source)
{
    int index = 0;
    foreach (T value in source)
    {
        yield return (index, value);
        index++;
    }
}
<System.Runtime.CompilerServices.Extension> _
Public Function WithIndex(Of T)(ByVal source As IEnumerable(Of T)) As IEnumerable(Of (index As Integer, value As T))
	Dim index As Integer = 0
	For Each value As T In source
		Yield (index, value)
		index += 1
	Next value
End Function
$vbLabelText   $csharpLabel

Maintenant, vous pouvez utiliser cette méthode d'extension avec vos collections :

int[] numbers = { 10, 20, 30, 40 };
foreach (var (index, value) in numbers.WithIndex())
{
    Console.WriteLine($"Index: {index}, Value: {value}");
}
int[] numbers = { 10, 20, 30, 40 };
foreach (var (index, value) in numbers.WithIndex())
{
    Console.WriteLine($"Index: {index}, Value: {value}");
}
Dim numbers() As Integer = { 10, 20, 30, 40 }
foreach var(index, value) In numbers.WithIndex()
	Console.WriteLine($"Index: {index}, Value: {value}")
Next
$vbLabelText   $csharpLabel

Cette approche crée une solution plus élégante au problème de foreach avec index en abstraisant la gestion manuelle de l'index dans une méthode réutilisable.

Utilisation d'une boucle while pour accéder aux index

Si vous travaillez avec des collections comme des tableaux ou des listes, vous pouvez utiliser une boucle while en conjonction avec une variable d'index pour accéder à la fois à l'index et à l'élément actuel :

int[] numbers = { 10, 20, 30, 40 };
int index = 0;
while (index < numbers.Length)
{
    Console.WriteLine($"Index: {index}, Value: {numbers[index]}");
    index++;
}
int[] numbers = { 10, 20, 30, 40 };
int index = 0;
while (index < numbers.Length)
{
    Console.WriteLine($"Index: {index}, Value: {numbers[index]}");
    index++;
}
Dim numbers() As Integer = { 10, 20, 30, 40 }
Dim index As Integer = 0
Do While index < numbers.Length
	Console.WriteLine($"Index: {index}, Value: {numbers(index)}")
	index += 1
Loop
$vbLabelText   $csharpLabel

C# foreach avec index (Comment cela fonctionne pour les développeurs) : Figure 1 - Sortie des index

Cette méthode vous permet d'accéder directement à la fois à l'index et à l'élément actuel en utilisant la variable d'index comme un indice pour le tableau ou la liste.

Collections personnalisées et itérateurs dans .NET

Si vous travaillez avec des collections personnalisées, vous pouvez implémenter vos propres itérateurs pour prendre en charge l'accès indexé. En implémentant l'interface IEnumerable et en utilisant l'instruction yield return, vous pouvez créer des itérateurs qui renvoient à la fois l'élément et son index.

Voici un exemple de création d'une collection personnalisée qui implémente IEnumerable :

public class CustomCollection<T> : IEnumerable<T>
{
    private T[] _items;
    public CustomCollection(T[] items)
    {
        _items = items;
    }
    public IEnumerator<T> GetEnumerator()
    {
        for (int i = 0; i < _items.Length; i++)
        {
            yield return _items[i];
        }
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
public class CustomCollection<T> : IEnumerable<T>
{
    private T[] _items;
    public CustomCollection(T[] items)
    {
        _items = items;
    }
    public IEnumerator<T> GetEnumerator()
    {
        for (int i = 0; i < _items.Length; i++)
        {
            yield return _items[i];
        }
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
Public Class CustomCollection(Of T)
	Implements IEnumerable(Of T)

	Private _items() As T
	Public Sub New(ByVal items() As T)
		_items = items
	End Sub
	Public Iterator Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
		For i As Integer = 0 To _items.Length - 1
			Yield _items(i)
		Next i
	End Function
	Private Iterator Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
		Return GetEnumerator()
	End Function
End Class
$vbLabelText   $csharpLabel

Vous pouvez ensuite utiliser cette collection personnalisée dans une boucle foreach :

var customCollection = new CustomCollection<int>(new int[] { 10, 20, 30, 40 });
foreach (int number in customCollection)
{
    Console.WriteLine(number);
}
var customCollection = new CustomCollection<int>(new int[] { 10, 20, 30, 40 });
foreach (int number in customCollection)
{
    Console.WriteLine(number);
}
Dim customCollection As New CustomCollection(Of Integer)(New Integer() { 10, 20, 30, 40 })
For Each number As Integer In customCollection
	Console.WriteLine(number)
Next number
$vbLabelText   $csharpLabel

En implémentant la méthode GetEnumerator et en utilisant yield return, vous créez un itérateur qui permet à la boucle foreach de fonctionner avec votre collection personnalisée comme avec n'importe quelle autre collection dans .NET.

Utilisation de dictionnaires et itération avec des paires clé-valeur

Lorsque vous travaillez avec des dictionnaires, la boucle foreach vous permet d'itérer directement sur les paires clé-valeur. C'est un cas d'utilisation courant pour accéder à la fois à la clé et à la valeur lors de chaque itération :

Dictionary<int, string> dict = new Dictionary<int, string>
{
    { 1, "Apple" },
    { 2, "Banana" },
    { 3, "Cherry" }
};
foreach (var kvp in dict)
{
    Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
}
Dictionary<int, string> dict = new Dictionary<int, string>
{
    { 1, "Apple" },
    { 2, "Banana" },
    { 3, "Cherry" }
};
foreach (var kvp in dict)
{
    Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
}
Dim dict As New Dictionary(Of Integer, String) From {
	{1, "Apple"},
	{2, "Banana"},
	{3, "Cherry"}
}
For Each kvp In dict
	Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}")
Next kvp
$vbLabelText   $csharpLabel

Dans cet exemple, kvp.Key vous donne la clé actuelle et kvp.Value vous donne la valeur actuelle.

Utilisation d'IronPDF avec C# foreach Loop et Index

C# foreach avec index (Comment cela fonctionne pour les développeurs) : Figure 2 - IronPDF

IronPDF est une bibliothèque PDF pour gérer la génération de PDF à partir de HTML et d'autres tâches liées aux PDF en C#. Il est également compatible avec le dernier .NET Framework. Lors de la génération de PDF avec IronPDF, vous pourriez avoir besoin d'itérer sur une collection de données et d'insérer dynamiquement du contenu dans votre fichier PDF. La combinaison de la boucle foreach avec la gestion des index vous permet de gérer le positionnement, la numérotation ou la logique personnalisée en fonction de l'index de l'élément actuel dans la collection. Voici un exemple pratique d'utilisation d'IronPDF pour créer un PDF où chaque élément d'une collection est inséré dans le document, avec son index.

using IronPdf;
class Program
{
    static void Main(string[] args)
    {
        // Create a new PDF document renderer
        var pdf = new ChromePdfRenderer();

        // Sample data array
        string[] items = { "First Item", "Second Item", "Third Item" };

        // Initialize the HTML content with foreach loop and index
        string htmlContent = "<html><body>";
        int index = 0;
        foreach (var item in items)
        {
            htmlContent += $"<h2>Item {index + 1}: {item}</h2>";
            index++;
        }
        htmlContent += "</body></html>";

        // Render the HTML to PDF
        var pdfDocument = pdf.RenderHtmlAsPdf(htmlContent);

        // Save the PDF document
        pdfDocument.SaveAs("output.pdf");

        // Notify completion
        Console.WriteLine("PDF created successfully with indexed items.");
    }
}
using IronPdf;
class Program
{
    static void Main(string[] args)
    {
        // Create a new PDF document renderer
        var pdf = new ChromePdfRenderer();

        // Sample data array
        string[] items = { "First Item", "Second Item", "Third Item" };

        // Initialize the HTML content with foreach loop and index
        string htmlContent = "<html><body>";
        int index = 0;
        foreach (var item in items)
        {
            htmlContent += $"<h2>Item {index + 1}: {item}</h2>";
            index++;
        }
        htmlContent += "</body></html>";

        // Render the HTML to PDF
        var pdfDocument = pdf.RenderHtmlAsPdf(htmlContent);

        // Save the PDF document
        pdfDocument.SaveAs("output.pdf");

        // Notify completion
        Console.WriteLine("PDF created successfully with indexed items.");
    }
}
Imports IronPdf
Friend Class Program
	Shared Sub Main(ByVal args() As String)
		' Create a new PDF document renderer
		Dim pdf = New ChromePdfRenderer()

		' Sample data array
		Dim items() As String = { "First Item", "Second Item", "Third Item" }

		' Initialize the HTML content with foreach loop and index
		Dim htmlContent As String = "<html><body>"
		Dim index As Integer = 0
		For Each item In items
			htmlContent &= $"<h2>Item {index + 1}: {item}</h2>"
			index += 1
		Next item
		htmlContent &= "</body></html>"

		' Render the HTML to PDF
		Dim pdfDocument = pdf.RenderHtmlAsPdf(htmlContent)

		' Save the PDF document
		pdfDocument.SaveAs("output.pdf")

		' Notify completion
		Console.WriteLine("PDF created successfully with indexed items.")
	End Sub
End Class
$vbLabelText   $csharpLabel

Voici le fichier PDF de sortie :

C# foreach avec index (Comment cela fonctionne pour les développeurs) : Figure 3 - Sortie PDF

Conclusion

C# foreach avec index (Comment cela fonctionne pour les développeurs) : Figure 4 - Licence

En C#, bien que la boucle foreach soit un moyen pratique d'itérer sur des collections, elle n'a pas de prise en charge native pour l'indexation. Cependant, il existe plusieurs façons de contourner cette limitation. Que vous utilisiez une simple variable d'index, la méthode Select de LINQ, ou des itérateurs personnalisés, vous pouvez accéder à l'index de l'élément actuel ou suivant lors de l'itération. Comprendre ces techniques peut vous aider à utiliser plus efficacement la boucle foreach, surtout lorsque vous avez besoin de connaître l'index de chaque élément.

Avec IronPDF, vous n'avez pas besoin de vous engager tout de suite. Nous offrons une version d'essai gratuite qui vous permet d'explorer en profondeur les capacités du logiciel. Si vous aimez ce que vous voyez, les licences commencent à $799.

Questions Fréquemment Posées

Comment puis-je suivre l'index des éléments dans une boucle foreach en C# ?

Pour suivre l'index dans une boucle foreach en C#, vous pouvez incrémenter manuellement une variable d'index séparée, utiliser la méthode Select de LINQ pour projeter les éléments avec leur index ou créer un itérateur personnalisé qui produit à la fois l'élément et son index.

Qu'est-ce que la méthode LINQ Select et comment aide-t-elle à l'indexation ?

La méthode LINQ Select peut transformer chaque élément d'une collection en une nouvelle forme qui inclut l'index de l'élément. Cette projection vous permet d'accéder à la fois à l'élément et à son index lors de l'itération dans une boucle foreach.

Comment puis-je créer un itérateur personnalisé pour l'indexation en C# ?

Un itérateur personnalisé en C# peut être créé en utilisant le mot-clé yield return. Cela vous permet de construire une méthode qui itère sur une collection et produit à la fois l'élément actuel et son index, simplifiant ainsi l'indexation de la boucle.

Une bibliothèque PDF peut-elle aider à créer du contenu indexé en C# ?

Oui, une bibliothèque PDF comme IronPDF peut être utilisée conjointement avec une boucle foreach en C# pour itérer sur des collections de données et insérer du contenu indexé dans un PDF. Cette approche permet un positionnement dynamique du contenu et un indexage précis.

Comment itérer sur un dictionnaire en utilisant une boucle foreach en C# ?

En C#, une boucle foreach peut itérer sur un dictionnaire en accédant à chaque paire clé-valeur. Cela permet aux développeurs de travailler directement avec les clés et les valeurs lors du processus d'itération.

Quels sont les avantages d'utiliser des bibliothèques PDF dans le développement en C# ?

Les bibliothèques PDF permettent aux développeurs de générer des PDF à partir de HTML et d'effectuer diverses manipulations PDF en C#. Elles offrent généralement des essais gratuits pour explorer les fonctionnalités, avec des licences disponibles à l'achat.

Comment la boucle while peut-elle être utilisée pour l'itération indexée en C# ?

Une boucle while peut être employée avec une variable d'index pour itérer sur des collections en C#, permettant d'accéder à la fois à l'index et à l'élément actuel en utilisant l'index en tant que sous-script.

Curtis Chau
Rédacteur technique

Curtis Chau détient un baccalauréat en informatique (Université de Carleton) et se spécialise dans le développement front-end avec expertise en Node.js, TypeScript, JavaScript et React. Passionné par la création d'interfaces utilisateur intuitives et esthétiquement plaisantes, Curtis aime travailler avec des frameworks modernes ...

Lire la suite