I generics consentono di sviluppare parti di codice independenti dal tipo dei dati e trovano la loro naturale applicazione nel riuso del codice.
Un contenitore di oggetti generici è indipendente dal tipo utilizzato: gli oggetti generici consentono di scrivere codice una sola volta e di poterlo riutilizzare con tutte le tipologie di dato passato in ingresso.
In questo articolo descriveremo come implementare classi / metodi generici.
Quando si crea un’istanza di una classe generica è necessario indicare il tipo dell’oggetto che dovrà essere gestito: l’indicazione viene data utilizzando il segnaposto generico T.
Supponendo di aver definito una classe generica, di averla chiamata ClasseGenerica e di voler gestire un membro di classe di tipo stringa, la sintassi da utilizzare sarà simile alla seguente:
ClasseGenerica <string> g = new ClasseGenerica <string>();
Nel caso di utilizzo della stessa classe con il membro di classe intero:
ClasseGenerica <int> g = new ClasseGenerica <int>();
Possiamo paragonare all’utilizzo di una classe generica come all’implementazione della seguente classe:
public class ClasseGenerica
{
public Stringa campo;
...
}
La convenzione utilizzata in C# indica che i parametri di tipo debbano:
- essere descrittivi
- iniziare con la lettera T
Inoltre è possibile indicare i seguenti vincoli sui parametri:
- “where T: struct” indica che l’argomento di tipo deve essere un tipo valore
- “where T: class” indica che l’argomento di tipo deve essere un tipo riferimento
- “where T: new()” indica che l’argomento di tipo deve disporre di un costruttore publico privo di parametro: se utilizzato insieme ad altri vincoli deve essere indicato per ultimo.
- “where T: nome_classe” indica che l’argomento di tipo deve corrispondere alla classe indicata oppure derivare da essa
- “where T: nome_interfaccia” indica che l’argomento di tipo deve corrispondere all’interfaccia indicata oppure implementarla
- “where T: U” indica che l’argomento di tipo fornito per T deve corrispondere a quello fornito per U
L’utilizzo di tipi generici può anche essere estesa alla definizione di metodi e delegati generici.
Di seguito un esempio di metodo generico:
public void Swap<T>(ref T a, ref T b)
{
T temp;
temp = a;
a = b;
b = temp;
}
e di delegato generico:
public delegate void DelegatoGenerico<T>(object oggetto, T datievento);