Indexeurs dans les interfaces (Guide de programmation C#)
Des indexeurs peuvent être déclarés dans une interface. Les accesseurs d’indexeurs d’interface se distinguent sur plusieurs plans des accesseurs d’indexeurs de classe, à savoir :
- Les accesseurs d’interface n’utilisent pas de modificateurs.
- Un accesseur d’interface n’a généralement pas de corps.
Un accesseur vise à indiquer si l’indexeur est en lecture-écriture, en lecture seule ou en écriture seule. Vous pouvez fournir une implémentation pour un indexeur défini dans une interface, mais cela est rare. Les indexeurs définissent généralement une API pour accéder aux champs de données, et les champs de données ne peuvent pas être définis dans une interface.
L’exemple ci-dessous porte sur un accesseur d’indexeur d’interface :
public interface ISomeInterface
{
//...
// Indexer declaration:
string this[int index]
{
get;
set;
}
}
La signature d’un indexeur doit se distinguer de tous les autres indexeurs déclarés dans la même interface.
Exemple
L’exemple suivant montre comment implémenter des indexeurs d’interface.
// Indexer on an interface:
public interface IIndexInterface
{
// Indexer declaration:
int this[int index]
{
get;
set;
}
}
// Implementing the interface.
class IndexerClass : IIndexInterface
{
private int[] arr = new int[100];
public int this[int index] // indexer declaration
{
// The arr object will throw IndexOutOfRange exception.
get => arr[index];
set => arr[index] = value;
}
}
IndexerClass test = new IndexerClass();
System.Random rand = System.Random.Shared;
// Call the indexer to initialize its elements.
for (int i = 0; i < 10; i++)
{
test[i] = rand.Next();
}
for (int i = 0; i < 10; i++)
{
System.Console.WriteLine($"Element #{i} = {test[i]}");
}
/* Sample output:
Element #0 = 360877544
Element #1 = 327058047
Element #2 = 1913480832
Element #3 = 1519039937
Element #4 = 601472233
Element #5 = 323352310
Element #6 = 1422639981
Element #7 = 1797892494
Element #8 = 875761049
Element #9 = 393083859
*/
Dans l’exemple précédent, vous pouvez utiliser l’implémentation de membre d’interface explicite en utilisant le nom qualifié complet du membre d’interface. Par exemple
string IIndexInterface.this[int index]
{
}
Cependant, le nom qualifié complet est seulement nécessaire pour éviter toute ambiguïté quand la classe implémente plusieurs interfaces avec la même signature d’indexeur. Par exemple, si une classe Employee
implémente deux interfaces, ICitizen
et IEmployee
, et que les deux interfaces ont la même signature d’indexeur, l’implémentation de membre d’interface explicite est nécessaire. Autrement dit, la déclaration d’indexeur suivante :
string IEmployee.this[int index]
{
}
Implémente l’indexeur dans l’interface IEmployee
, alors que la déclaration suivante :
string ICitizen.this[int index]
{
}
Implémente l’interface dans l’interface ICitizen
.