Indicizzatori nelle interfacce (Guida per programmatori C#)

Gli indicizzatori possono essere dichiarati su una interfaccia. Le funzioni di accesso degli indicizzatori di interfaccia differiscono dalle funzioni di accesso degli indicizzatori di classe per gli aspetti seguenti:

  • Le funzioni di accesso di interfaccia non usano modificatori.
  • Una funzione di accesso all'interfaccia in genere non dispone di un corpo.

Lo scopo della funzione di accesso è quello di indicare se l'indicizzatore è in lettura-scrittura, in sola lettura o in sola scrittura. È possibile fornire un'implementazione per un indicizzatore definito in un'interfaccia, ma questa operazione è rara. Gli indicizzatori in genere definiscono un'API per accedere ai campi dati e i campi dati non possono essere definiti in un'interfaccia.

Nell'esempio seguente viene illustrata la funzione di accesso di un indicizzatore di interfaccia:

public interface ISomeInterface
{
    //...

    // Indexer declaration:
    string this[int index]
    {
        get;
        set;
    }
}

È necessario che la firma di un indicizzatore sia diversa dalle firme di tutti gli altri indicizzatori dichiarati nella stessa interfaccia.

Esempio

Nell'esempio seguente viene illustrato come implementare gli indicizzatori di interfaccia.

// 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
*/

Nell'esempio precedente era possibile adottare l'implementazione esplicita del membro dell'interfaccia usando il nome completo del membro dell'interfaccia. Ad esempio:

string IIndexInterface.this[int index]
{
}

Il nome completo, tuttavia, è necessario soltanto per evitare l'ambiguità quando la classe implementa più di un'interfaccia con la stessa firma di indicizzatore. Se una classe Employee implementa, ad esempio, due interfacce, ICitizen e IEmployee, ed entrambe le interfacce hanno la stessa firma di indicizzatore, sarà necessaria l'implementazione esplicita del membro dell'interfaccia. In altre parole, la dichiarazione di indicizzatore seguente:

string IEmployee.this[int index]
{
}

Implementa l'indicizzatore nell'interfaccia IEmployee, mentre la dichiarazione seguente:

string ICitizen.this[int index]
{
}

Implementa l'indicizzatore nell'interfaccia ICitizen.

Vedi anche