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.

Voir aussi