Condividi tramite


Tipi generici in Visual Basic

Aggiornamento: novembre 2007

Un tipo generico è un elemento di programmazione singolo in grado di eseguire le funzionalità di vari tipi di dati. Quando si definisce una classe o una routine generica, non è necessario definire una versione distinta per ogni tipo di dati per cui si desidera implementare la funzionalità.

Un esempio analogo è un cacciavite con punte rimovibili. Si esamina la vite da avvitare e si sceglie la punta corretta per tale vite (a taglio, a croce, a stella). Dopo avere inserito la punta corretta nel manico del cacciavite, si esegue la stessa operazione in tutti i casi, cioè si fa ruotare la vite.

Cacciavite come strumento generico

Diagramma di un cacciavite impostato come strumento generico

Quando si definisce un tipo generico, se ne impostano i parametri con uno o più tipi di dati. In tal modo, il codice che lo utilizzerà potrà adattare i tipi di dati ai propri requisiti. Il codice può dichiarare più elementi di programmazione diversi a partire dall'elemento generico, ciascuno dei quali agisce su un diverso insieme di tipi di dati, per tutti gli elementi dichiarati viene tuttavia applicata la medesima logica, indipendentemente dai tipi di dati utilizzati.

Si supponga ad esempio di voler creare e utilizzare una classe Queue che agisca su un particolare tipo di dati, quale il tipo String. Questa classe può essere dichiarata dalla classe System.Collections.Generic.Queue<T>, come illustrato nell'esempio seguente.

Public stringQ As New System.Collections.Generic.Queue(Of String)

Ora è possibile utilizzare stringQ per lavorare esclusivamente con valori String. Poiché stringQ è specifica per String anziché essere generalizzata per i valori Object, non si verifica un'associazione tardiva né una conversione di tipi. In questo modo si riduce il tempo di esecuzione e la possibilità che si verifichino errori di runtime.

Per ulteriori informazioni sull'utilizzo di un tipo generico, vedere Procedura: utilizzare una classe generica.

Esempio di una classe generica

Nell'esempio riportato di seguito viene illustrata la definizione di base di una classe generica.

Public Class classHolder(Of t)
    Public Sub processNewItem(ByVal newItem As t)
        Dim tempItem As t
        ' Insert code that processes an item of data type t.
    End Sub
End Class

Nella definizione di base precedente, t è un parametro di tipo, ovvero un segnaposto per un tipo di dati fornito quando si dichiara la classe. In altri punti del codice è possibile dichiarare varie versioni di classHolder fornendo vari tipi di dati per t. Nell'esempio che segue vengono illustrate due dichiarazioni di questo tipo.

Public integerClass As New classHolder(Of Integer)
Friend stringClass As New classHolder(Of String)

Nelle istruzioni precedenti vengono dichiarate delle classi costruite, in cui il parametro di tipo viene sostituito da un tipo specifico. Questa sostituzione viene propagata in tutto il codice all'interno della classe costruita. Nell'esempio seguente viene mostrato come si presenta la routine processNewItem in integerClass.

Public Sub processNewItem(ByVal newItem As Integer)
    Dim tempItem As Integer
    ' Inserted code now processes an Integer item.
End Sub

Per un esempio più esaustivo, vedere Procedura: definire una classe in grado di fornire funzionalità identiche con tipi di dati diversi.

Elementi di programmazione idonei

È possibile definire e utilizzare classi, strutture, interfacce, routine e delegati generici. Tenere presente che in .NET Framework vengono definite svariate classi, strutture e interfacce generiche che rappresentano elementi generici di uso comune. Lo spazio dei nomi System.Collections.Generic fornisce dizionari, elenchi, code e stack. Prima di definire un elemento generico personalizzato, verificare se non è già disponibile in System.Collections.Generic.

Le routine non sono tipi, ma è possibile definire e utilizzare routine generiche. Per informazioni, vedere Routine generiche in Visual Basic.

Vantaggi dei tipi generici

Un tipo generico è l'elemento su cui si basa la dichiarazione di vari elementi di programmazione diversi, ciascuno dei quali agisce su un particolare tipo di dati. Le alternative a un tipo generico sono le seguenti:

  1. Un singolo tipo che agisce sul tipo di dati Object.

  2. Un insieme di versioni specifiche di un tipo, ciascuna delle quali è codificata individualmente e agisce su un particolare tipo di dati, quale String o Integer o su un tipo definito dall'utente, come ad esempio customer.

Rispetto a queste alternative, un tipo generico presenta i vantaggi seguenti:

  • Indipendenza dai tipi. I tipi generici consentono di eseguire il controllo dei tipi in fase di compilazione. I tipi basati su Object accettano qualsiasi tipo di dati ed è quindi necessario scrivere del codice che permetta di verificare se un tipo di dati di input è accettabile. Con i tipi generici, invece, il compilatore è in grado di individuare i tipi non corrispondenti prima della fase di esecuzione.

  • Prestazioni. Con i tipi generici non è necessario eseguire il boxing e l'unboxing dai dati, perché ognuno è specializzato per un tipo di dati. Per le operazioni basate su Object, invece, è necessario eseguire il boxing dei tipi di dati di input per convertirli in Object ed eseguire l'unboxing dei dati destinati all'output. Eseguire il boxing e l'unboxing comporta un peggioramento delle prestazioni.

    I tipi basati su Object sono inoltre caratterizzati da associazione tardiva, e questo implica che, per accedere ai loro membri, è necessario codice supplementare in fase di esecuzione. Anche questo comporta un peggioramento delle prestazioni.

  • Consolidamento del codice. Il codice di un tipo generico deve essere definito una volta soltanto. Un insieme di versioni specifiche di un tipo, invece, deve replicare lo stesso codice in ogni versione, e la sola differenza è il tipo di dati specifico di quella versione. Nel caso dei tipi generici, tutte le versioni specifiche di un tipo vengono generate dal tipo generico originale.

  • Riutilizzo del codice. Il codice che non dipende da una particolare tipo di dati può essere riutilizzato con vari tipi di dati se si tratta di codice generico. Spesso lo si può perfino riutilizzare con un tipo di dati che in origine non era stato previsto.

  • Supporto dell'ambiente IDE. Se si utilizza un tipo costruito dichiarato da un tipo generico, l'ambiente di sviluppo integrato (IDE, Integrated Development Environment) offre maggiore supporto durante lo sviluppo del codice. La tecnologia IntelliSense™, ad esempio, può visualizzare le opzioni specifiche del tipo per l'argomento di un costruttore o di un metodo.

  • Algoritmi generici. Gli algoritmi astratti indipendenti dal tipo sono possibili candidati per i tipi generici. Una routine generica che ordina degli elementi per mezzo dell'interfaccia IComparable, ad esempio, può essere utilizzata con qualsiasi tipo di dati che implementi IComparable.

Vincoli

Sebbene il codice di una definizione di tipo generico debba essere quanto più possibile indipendente dal tipo, potrebbe essere necessario che il tipo di dati fornito al tipo generico debba possedere determinate caratteristiche. Se ad esempio si desidera confrontare fra loro due elementi per ordinarli, il loro tipo di dati deve implementare l'interfaccia IComparable. Questo requisito può essere attivato aggiungendo un vincolo al parametro di tipo.

Esempio di vincolo

Nell'esempio seguente viene illustrata una definizione di base di una classe con un vincolo che richiede che l'argomento di tipo implementi l'interfaccia IComparable.

Public Class itemManager(Of t As IComparable)
    ' Insert code that defines class members.
End Class

Se il codice successivo tenta di costruire una classe da itemManager fornendo un tipo che non implementa IComparable, viene segnalato un errore.

Tipi di vincoli

Il vincolo consente di specificare i seguenti requisiti in qualsiasi combinazione:

  • L'argomento di tipo deve implementare una o più interfacce

  • L'argomento di tipo deve essere del tipo di, o ereditato da, non più di una classe.

  • L'argomento di tipo deve esporre un costruttore senza parametri accessibile al codice che crea oggetti da esso.

  • L'argomento di tipo deve essere un tipo di riferimento oppure un tipo di valore.

Se è necessario imporre più requisiti, utilizzare un elenco di vincoli separati da virgole racchiuso fra parentesi graffe ({ }). Per richiedere un costruttore accessibile, includere nell'elenco la parola chiave New (Visual Basic). Per richiedere un tipo di riferimento, includere la parola chiave Class (Visual Basic); per richiedere un tipo di valore, includere la parola chiave Structure (Visual Basic).

Per ulteriori informazioni sui vincoli, vedere Elenco dei tipi.

Esempio di vincoli multipli

Nell'esempio seguente viene illustrata una definizione di base di una classe generica con un elenco di vincoli per il parametro di tipo. Nel codice che crea un'istanza di questa classe, l'argomento di tipo deve implementare sia l'interfaccia IComparable che l'interfaccia IDisposable, deve essere un tipo di riferimento e deve esporre un costruttore senza parametri accessibile.

Public Class thisClass(Of t As {IComparable, IDisposable, Class, New})
    ' Insert code that defines class members.
End Class

Terminologia

Con la trattazione dei tipi generici vengono introdotti e utilizzati i termini seguenti:

  • Tipo generico Definizione di una classe, una struttura, un'interfaccia, una routine o un delegato per cui viene fornito almeno un tipo di dati quando lo si dichiara.

  • Parametro di tipo. In una definizione di tipo generico, segnaposto per il tipo di dati fornito quando si dichiara il tipo.

  • Argomento di tipo. Tipo di dati specifico che sostituisce un parametro di tipo quando si dichiara un tipo costruito da un tipo generico.

  • Vincolo. Condizione utilizzata per un parametro di tipo che limita l'argomento di tipo che può essere fornito. Un vincolo può richiedere che l'argomento di tipo implementi una particolare interfaccia, che appartenga o erediti da una determinata classe, che esponga un costruttore senza parametri accessibile o che sia un tipo di riferimento o di valore. Questi vincoli possono essere combinati fra loro, ma non è possibile specificare più di una classe.

  • Tipo costruito. Classe, struttura, interfaccia, routine o delegato dichiarato da un tipo generico fornendo argomenti di tipo per i parametri di tipo.

Vedere anche

Attività

Risoluzione dei problemi relativi ai tipi di dati

Concetti

Tipi di dati in Visual Basic

Caratteri tipo

Tipi valore e tipi riferimento

Riferimenti

Riepilogo dei tipi di dati (Visual Basic)

Of

As

Tipo di dati Object

Altre risorse

Implementazione del tipo di dati

Conversioni di tipi in Visual Basic