Condividi tramite


Cenni preliminari sui generics in Visual C++

I generics sono tipi con parametri supportati da Common Language Runtime.Un tipo con parametri è un tipo definito con un parametro di tipo sconosciuto specificato quando l'oggetto generico viene utilizzato.

Poiché i generics?

I supporta i modelli C++ e i modelli che i generics supportano i tipi con parametri per creare classi di raccolte tipizzato.Tuttavia, i modelli forniscono la parametrizzazione in fase di compilazione.Non è possibile fare riferimento a un assembly contenente una definizione di modello e creare nuove specializzazioni del modello.Una volta compilato, simile specializzati di un modello in qualsiasi altra classe o metodo.A il contrario, i generics viene generato in MSIL come tipo con parametri noto dal runtime per essere un tipo con parametri; il codice sorgente che fa riferimento a un assembly che contiene un tipo generico può creare le specializzazioni di tipo generico.Per ulteriori informazioni sul confronto dei modelli e dei generics di Visual C++, vedere Generics e modelli (Visual C++).

funzioni generiche e tipi

I tipi di classe, purché siano tipi gestiti, possono essere generici.Un esempio di questo potrebbe essere una classe di List .Il tipo di oggetto nell' elenco sarebbe il parametro di tipo.Se è necessaria una classe di List per molti tipi diversi di oggetti, prima che i generics è possibile utilizzare List che accetta System::Object come tipo di elemento.Ma che consentirebbe qualsiasi oggetto inclusi oggetti del tipo errato) da utilizzare nell' elenco.Tale elenco viene chiamato una classe di raccolte non tipizzata.Idealmente, è possibile controllare il tipo in fase di esecuzione e generare un'eccezione.In alternativa, è possibile utilizzare un modello, che causerebbe perdita della qualità generica compilata una volta in un assembly.Gli utenti dell' assembly non possono creare le rispettive specializzazioni del modello.I generics consente di creare le classi di raccolte tipizzato, indica List<int> (lettura come “elenco di int„) e List<double> (“elenco a doppio„) che genererebbero un errore in fase di compilazione se si tenta di inserire un tipo che la raccolta non è stata progettata per accettare la raccolta tipizzata.Inoltre, questi tipi rimangono generici dopo la compilazione.

Una descrizione della sintassi di classi generiche è disponibile in nuovo Classi generiche (C++/CLI)spazio dei nomi di. Su, System.Collections.Generic, in viene introdotto un set di tipi di raccolta con parametri inclusi Dictionary<TKey, TValue>, List<T> e LinkedList<T>.Per ulteriori informazioni, vedere Generics nella libreria di classi .NET Framework (Guida per programmatori C#).

Sia l'istanza che un membro di classe statico viene eseguita, delegati e le funzioni globali possono anche essere generiche.Le funzioni generiche possono essere necessario anche se i parametri di funzione sono di un tipo sconosciuto, o se la funzione stessa necessario utilizzare i tipi generici.In molti casi in cui System::Object può essere utilizzato in passato come parametro per un tipo di oggetto sconosciuto, un parametro di tipo generico è possibile utilizzare invece, perché l'accesso a più codice indipendente dai tipi.Qualsiasi tentativo di passare un tipo che la funzione non è stata progettata per essere contrassegnato come errore in fase di compilazione.Utilizzando System::Object come parametro della funzione, il passaggio non intenzionale di un oggetto di cui la funzione non era prevista per gestire non verrebbe rilevato e sarà necessario eseguire il cast del tipo di oggetto sconosciuto a un tipo specifico nel corpo della funzione e rappresenta la possibilità di un InvalidCastException.Con un oggetto generico, il codice che tenta di passare un oggetto alla funzione può provocare un conflitto di tipi in modo che il corpo della funzione è garantito che il tipo corretto.

Gli stessi vantaggi alle classi di raccolte basano sui generics.Le classi di raccolte in passato utilizza System::Object per archiviare gli elementi in una raccolta.L'inserimento degli oggetti di un tipo che la raccolta non è stata progettata per non è stato contrassegnato come in fase di compilazione e spesso neanche se gli oggetti sono stati immessi.In genere, un oggetto viene eseguito il cast su un altro tipo quando è stato eseguito nella raccolta.Solo quando il cast ha esito negativo il tipo imprevisto verrebbe rilevato.I generics risolve il problema in fase di compilazione rileva qualsiasi codice che inserisce un tipo che non corrisponda (o in modo implicito convertito) il parametro di tipo della raccolta generica.

Per una descrizione della sintassi, vedere Funzioni generiche (C++/CLI).

Terminologia utilizzata con i generics

c570k3f3.collapse_all(it-it,VS.110).gifParametri di tipo

Una dichiarazione generica contiene uno o più tipi sconosciuti noti come i parametri di tipo.I parametri di tipo vengono forniti un nome che corrisponde al tipo nel corpo della dichiarazione generica.Il parametro di tipo viene utilizzato come tipo nel corpo della dichiarazione generica.La dichiarazione generica per list<t> contiene il parametro di tipo T.

c570k3f3.collapse_all(it-it,VS.110).gifargomenti di tipo

L'argomento di tipo è il tipo effettivo utilizzato al posto del parametro di tipo quando l'oggetto generico è specializzato per un tipo specifico o i tipi.Ad esempio, int è l'argomento di tipo in List<int>.I tipi di valore e tipi di handle sono gli unici tipi consentiti in come argomento di tipo generico.

c570k3f3.collapse_all(it-it,VS.110).giftipo costruito

Un tipo costruito da un tipo generico viene considerato un tipo costruito.Un tipo non completamente specificato, come List<T> è un tipo costruito aperto, un tipo completamente specificato, come List<double>, è un tipo costruito chiuso o tipo specializzato.Il è costruito i tipi può essere utilizzato nella definizione di altri tipi generici o metodi e non può essere completamente specificato fino a specificare viene generica stesso.Ad esempio, è un utilizzo di un tipo costruito aperto come classe base per una classe generica:

// generics_overview.cpp

// compile with: /clr /c

generic <typename T>

ref class List {};

generic <typename T>

ref class Queue : public List<T> {};

c570k3f3.collapse_all(it-it,VS.110).gifVincolo

un vincolo è una restrizione sui tipi che possono essere utilizzati come parametro di tipo.Ad esempio, una classe generica specificata può accettare solo le classi che ereditano da una determinata classe, o implementa un'interfaccia specificata.Per ulteriori informazioni, vedere Vincoli su parametri di tipo generico (C++/CLI).

Tipi di riferimento e tipi di valore

I tipi e i tipi di valore di handle possono essere utilizzate come argomenti di tipo.In la definizione generica, in cui qualsiasi tipo può essere utilizzato, la sintassi è quella dei tipi di riferimento.Ad esempio, l'operatore di -> viene utilizzato per accedere ai membri del tipo del parametro di tipo se il tipo verrà utilizzato è un tipo di riferimento o un tipo di valore.Quando un tipo di valore viene utilizzato come argomento di tipo, il runtime genera il codice che utilizza tipi di valore direttamente senza eseguirne il boxing.

Quando si utilizza un tipo di riferimento come argomento di tipo generico, utilizzare la sintassi di handle.Quando si utilizza un tipo di valore come argomento di tipo generico, utilizzare direttamente il nome del tipo.

// generics_overview_2.cpp

// compile with: /clr

generic <typename T>

ref class GenericType {};

ref class ReferenceType {};

value struct ValueType {};

int main() {

GenericType<ReferenceType^> x;

GenericType<ValueType> y;

}

Parametri di tipo

I parametri di tipo in una classe generica vengono considerati come altri identificatori.Tuttavia, poiché il tipo non è noto, esistono restrizioni sul relativo utilizzo.Ad esempio, non è possibile utilizzare i membri e i metodi del parametro di tipo classe a meno che il parametro di tipo è noto per supportare questi membri.Ovvero per accedere a un membro con il parametro di tipo, è necessario aggiungere il tipo contenente il membro all' elenco di vincoli del parametro di tipo.

// generics_overview_3.cpp

// compile with: /clr

interface class I {
   void f1();
   void f2();
};

ref struct R : public I {
   virtual void f1() {}
   virtual void f2() {} 
   virtual void f3() {} 
};

generic <typename T>
where T : I
void f(T t) {
   t->f1();
   t->f2();
   safe_cast<R^>(t)->f3();
}

int main() {
   f(gcnew R());
}

queste restrizioni si applicano agli operatori anche.Un parametro di tipo generico non vincolato non è possibile utilizzare gli operatori di != e di == per confrontare due istanze del parametro di tipo, nel caso il tipo non supporta questi operatori.Questi controlli sono necessari per i generics, ma non per i modelli, poiché i generics è possibile specializzare in fase di esecuzione da qualsiasi classe che soddisfa i vincoli, quando è troppo tardi per verificare l'utilizzo dei membri non validi.

Un'istanza predefinita del parametro di tipo può essere creata utilizzando l'operatore di () .Di seguito è riportato un esempio:

T t = T();

dove T è un parametro di tipo in una classe o in una definizione di metodo generico, inizializza la variabile sul valore predefinito.Se T è una classe di riferimento è un puntatore null; se T è una classe di valore, l'oggetto viene inizializzato su zero.Si tratta di un inizializzatore predefinito.

Vedere anche

Altre risorse

Generics (Estensioni del componente C++)