Condividi tramite


Classi e metodi generici

Generics introduce il concetto di parametri di tipo in .NET. I generics consentono di progettare classi e metodi che rinviano la specifica di uno o più parametri di tipo fino a quando non si usa la classe o il metodo nel codice. Ad esempio, usando un parametro di tipo generico T, è possibile scrivere una singola classe che può essere usata da un altro codice client senza incorrere nel costo o nel rischio di cast di runtime o operazioni di boxing, come illustrato di seguito:

// Declare the generic class.
public class GenericList<T>
{
    public void Add(T item) { }
}

public class ExampleClass { }

class TestGenericList
{
    static void Main()
    {
        // Create a list of type int.
        GenericList<int> list1 = new();
        list1.Add(1);

        // Create a list of type string.
        GenericList<string> list2 = new();
        list2.Add("");

        // Create a list of type ExampleClass.
        GenericList<ExampleClass> list3 = new();
        list3.Add(new ExampleClass());
    }
}

Le classi e i metodi generici combinano riutilizzabilità, sicurezza dei tipi ed efficienza in modo che le controparti non generiche non possano. I parametri di tipo generico vengono sostituiti con gli argomenti di tipo durante la compilazione. Nell'esempio precedente il compilatore sostituisce T con int. I generics vengono usati più frequentemente con le raccolte e i metodi che operano su di loro. Lo spazio dei nomi System.Collections.Generic contiene diverse classi di raccolta basate su tipi generici. Le raccolte non generiche, ad esempio ArrayList non sono consigliate e vengono mantenute solo a scopo di compatibilità. Per altre informazioni, vedere Generics in .NET.

È anche possibile creare tipi generici e metodi personalizzati per fornire soluzioni generalizzate, modelli di progettazione che siano sicuri di tipo ed efficienti. Nell'esempio di codice seguente viene illustrata una semplice classe di elenco collegato generico a scopo dimostrativo. Nella maggior parte dei casi, è consigliabile usare la List<T> classe fornita da .NET anziché crearne di personalizzate. Il parametro T di tipo viene usato in diverse posizioni in cui in genere viene usato un tipo concreto per indicare il tipo dell'elemento archiviato nell'elenco:

  • Come tipo di un parametro del metodo nel metodo AddHead.
  • Come tipo di ritorno della proprietà Data nella classe nidificata Node.
  • In qualità di tipo del membro privato data nella classe nidificata.

T è disponibile per la classe nidificata Node . Quando si crea un'istanza di GenericList<T> con un tipo concreto, ad esempio come GenericList<int>, ogni occorrenza di T è sostituita con int.

// Type parameter T in angle brackets.
public class GenericList<T>
{
    // The nested class is also generic, and
    // holds a data item of type T.
    private class Node(T t)
    {
        // T as property type.
        public T Data { get; set; } = t;

        public Node? Next { get; set; }
    }

    // First item in the linked list
    private Node? head;

    // T as parameter type.
    public void AddHead(T t)
    {
        Node n = new(t);
        n.Next = head;
        head = n;
    }

    // T in method return type.
    public IEnumerator<T> GetEnumerator()
    {
        Node? current = head;

        while (current is not null)
        {
            yield return current.Data;
            current = current.Next;
        }
    }
}

Nell'esempio di codice seguente viene illustrato come il codice client usa la classe generica GenericList<T> per creare un elenco di numeri interi. Se si modifica l'argomento di tipo, il codice seguente crea elenchi di stringhe o qualsiasi altro tipo personalizzato:

// A generic list of int.
GenericList<int> list = new();

// Add ten int values.
for (int x = 0; x < 10; x++)
{
    list.AddHead(x);
}

// Write them to the console.
foreach (int i in list)
{
    Console.WriteLine(i);
}

Console.WriteLine("Done");

Annotazioni

I tipi generici non sono limitati alle classi. Gli esempi precedenti usano tipi class, ma è possibile definire tipi generici interface e struct, inclusi i tipi record.

Panoramica dei generics

  • Usare tipi generici per ottimizzare il riutilizzo del codice, la sicurezza dei tipi e le prestazioni.
  • L'uso più comune dei generics consiste nel creare classi di raccolta.
  • La libreria di classi .NET contiene diverse classi di raccolte generiche nello spazio dei nomi System.Collections.Generic. Le raccolte generiche dovrebbero essere usate piuttosto che classi come ArrayList, quando possibile, nello spazio dei nomi System.Collections.
  • È possibile creare interfacce, classi, metodi, eventi e delegati generici personalizzati.
  • Le classi generiche possono essere vincolate per consentire l'accesso ai metodi in tipi di dati specifici.
  • È possibile ottenere informazioni in fase di esecuzione sui tipi usati in un tipo di dati generico tramite reflection.

Specificazione del linguaggio C#

Per altre informazioni, vedere la specifica del linguaggio C#.

Vedere anche