Qu'est-ce que les index en C# ? Quels types d'index existent et les avez-vous utilisés en pratique ?
sobes.tech IA
Réponse de l'IA
Les indexeurs en C# permettent d’accéder à une instance d’une classe ou d’une structure comme à un tableau, en utilisant la syntaxe []. Ils ne sont pas statiques et surchargent l’opérateur [].
Indexeurs
Les indexeurs permettent de définir la logique d’accès aux éléments d’une collection ou d’une structure de données à l’intérieur d’une classe.
public class MyCollection
{
private string[] data = new string[10];
// Indexeur permettant d’obtenir ou de définir un élément par indice
public string this[int index]
{
get
{
// Vérification des limites
if (index >= 0 && index < data.Length)
{
return data[index];
}
else
{
throw new IndexOutOfRangeException();
}
}
set
{
// Vérification des limites
if (index >= 0 && index < data.Length)
{
data[index] = value;
}
else
{
throw new IndexOutOfRangeException();
}
}
}
}
Types de paramètres des indexeurs
Les indexeurs peuvent accepter n’importe quel nombre de paramètres de n’importe quel type, pas seulement des types entiers.
public class DictionaryLike
{
private Dictionary<string, string> _dictionary = new Dictionary<string, string>();
// Indexeur avec paramètre de type string
public string this[string key]
{
get
{
if (_dictionary.ContainsKey(key))
{
return _dictionary[key];
}
else
{
return null; // Ou lancer une exception
}
}
set
{
_dictionary[key] = value;
}
}
}
Surcharge des indexeurs
Il est possible de créer des indexeurs surchargés avec différentes signatures (ensemble et types de paramètres).
public class Matrix
{
private int[,] data;
public Matrix(int rows, int cols)
{
data = new int[rows, cols];
}
// Indexeur avec deux paramètres entiers
public int this[int row, int col]
{
get
{
// Vérification des limites
if (row >= 0 && row < data.GetLength(0) && col >= 0 && col < data.GetLength(1))
{
return data[row, col];
}
else
{
throw new IndexOutOfRangeException();
}
}
set
{
// Vérification des limites
if (row >= 0 && row < data.GetLength(0) && col >= 0 && col < data.GetLength(1))
{
data[row, col] = value;
}
else
{
throw new IndexOutOfRangeException();
}
}
}
}
Indices de plage (Ranges & Indices)
En C# 8.0, de nouveaux types System.Index et System.Range ont été introduits, permettant d’utiliser la syntaxe pour accéder aux éléments depuis la fin de la collection (^) et pour obtenir des sous-plages (..). Ces concepts sont souvent appelés "indices", mais ils diffèrent des indexeurs classiques.
using System;
public class ArrayExample
{
public static void Main(string[] args)
{
string[] words = { "the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog" };
// Utilisation de System.Index pour accéder depuis la fin
Index last = ^1; // Index du dernier élément
Console.WriteLine(words[last]); // dog
// Utilisation de System.Range pour obtenir un sous-plage
Range middle = 1..4; // Éléments de l’indice 1 à (mais sans inclure) l’indice 4
string[] subset = words[middle]; // {"quick", "brown", "fox"}
// Range avec utilisation de System.Index
Range fromEnd = ^3..; // du troisième depuis la fin jusqu’à la fin
string[] suffix = words[fromEnd]; // {"the", "lazy", "dog"}
}
}
Application pratique
J’ai utilisé activement les indexeurs lors de la création de mes propres classes de collections ou de wrappers sur des collections existantes pour fournir un accès plus intuitif aux données. Par exemple :
- Développement de classes représentant des matrices ou des données multidimensionnelles, où l’accès par coordonnées
matrix[row, col]était logique. - Création de wrappers sur
Dictionary<>ou d’autres collections, où l’accès par clé via l’indexeur améliorait la lisibilité du code. - Dans des collections simples, où un accès syntaxique pratique, semblable à un tableau, était nécessaire.
J’ai utilisé les indices de plage (System.Index et System.Range) pour un accès plus concis à des parties de tableaux ou de listes, ce qui est particulièrement utile lors du travail avec des sous-chaînes ou des données partielles d’une collection.