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
.