Metodi generici (Guida per programmatori C#)

I metodi generici sono metodi dichiarati con parametri di tipo, come illustrato di seguito:

static void Swap<T>(ref T lhs, ref T rhs)
{
    T temp;
    temp = lhs;
    lhs = rhs;
    rhs = temp;
}

Nell'esempio di codice seguente viene illustrato un modo per chiamare il metodo utilizzando int come argomento di tipo:

public static void TestSwap()
{
    int a = 1;
    int b = 2;

    Swap<int>(ref a, ref b);
    System.Console.WriteLine(a + " " + b);
}

È anche possibile omettere l'argomento di tipo, che verrà dedotto dal compilatore. La seguente chiamata a Swap è equivalente alla precedente:

Swap(ref a, ref b);

Le regole per l'inferenza dei tipi sono valide anche per i metodi statici e i metodi di istanza. Il compilatore è in grado di dedurre i parametri di tipo in base agli argomenti del metodo passati, ma non unicamente da un vincolo o da un valore restituito, pertanto l'inferenza dei tipi non funziona con metodi privi di parametri. L'inferenza dei tipi si verifica in fase di compilazione, prima che il compilatore tenti di risolvere le firme del metodo di overload. Il compilatore applica la logica dell'inferenza dei tipi a tutti i metodi generici che condividono lo stesso nome. Nel passaggio di risoluzione dell'overload il compilatore include solo metodi generici per i quali l'inferenza dei tipi ha avuto esito positivo.

All'interno di una classe generica i metodi non generici possono accedere ai parametri di tipo a livello di classe, come illustrato di seguito:

class SampleClass<T>
{
    void Swap(ref T lhs, ref T rhs) { }
}

Se si definisce un metodo generico che accetta gli stessi parametri di tipo della classe che lo contiene, il compilatore genererà il messaggio di avviso CS0693 perché nell'ambito del metodo l'argomento fornito per il parametro T interno nasconderà quello specificato per il parametro T esterno. Se è necessario disporre di maggiore flessibilità durante la chiamata a un metodo di classe generico con argomenti di tipo diversi da quelli forniti al momento della creazione di un'istanza della classe, è consigliabile specificare un altro identificatore per il parametro di tipo del metodo, come illustrato in GenericList2<T> nell'esempio seguente.

class GenericList<T>
{
    // CS0693
    void SampleMethod<T>() { }
}

class GenericList2<T>
{
    //No warning
    void SampleMethod<U>() { }
}

Utilizzare i vincoli per consentire operazioni più specifiche sui parametri di tipo nei metodi. Questa versione di Swap<T>, ora denominata SwapIfGreater<T>, può essere utilizzata solo con argomenti di tipo che implementino IComparable<T>.

void SwapIfGreater<T>(ref T lhs, ref T rhs) where T : System.IComparable<T>
{
    T temp;
    if (lhs.CompareTo(rhs) > 0)
    {
        temp = lhs;
        lhs = rhs;
        rhs = temp;
    }
}

Per l'overload di metodi generici è possibile utilizzare diversi parametri di tipo. Tutti i metodi riportati di seguito possono, ad esempio, risiedere nella stessa classe:

void DoWork() { }
void DoWork<T>() { }
void DoWork<T, U>() { }

Specifiche del linguaggio C#

Per ulteriori informazioni, vedere Specifiche del linguaggio C#.

Vedere anche

Riferimenti

Introduzione ai generics (Guida per programmatori C#)

System.Collections.Generic

Metodi (Guida per programmatori C#)

Concetti

Guida per programmatori C#