Reflection e tipi genericiReflection and Generic Types

Dal punto di vista della reflection, un tipo ordinario si differenzia da un tipo generico perché quest'ultimo è associato a un insieme di parametri di tipo, se è una definizione di tipo generico, o a un insieme di argomenti di tipo, se è un tipo costruito.From the point of view of reflection, the difference between a generic type and an ordinary type is that a generic type has associated with it a set of type parameters (if it is a generic type definition) or type arguments (if it is a constructed type). Un metodo generico si differenzia da un metodo ordinario esattamente nello stesso modo.A generic method differs from an ordinary method in the same way.

Per comprendere come i tipi e i metodi generici vengono gestiti dalla reflection, è opportuno considerare due fattori fondamentali:There are two keys to understanding how reflection handles generic types and methods:

  • I parametri di tipo delle definizioni di tipo e di metodo generico sono rappresentati da istanze della classe Type .The type parameters of generic type definitions and generic method definitions are represented by instances of the Type class.

    Nota

    Numerosi metodi e proprietà di Type hanno un comportamento diverso quando un oggetto Type rappresenta un parametro di tipo generico.Many properties and methods of Type have different behavior when a Type object represents a generic type parameter. Queste differenze sono illustrate negli argomenti relativi alle proprietà e ai metodi in questione.These differences are documented in the property and method topics. Vedere ad esempio IsAutoClass e DeclaringType.For example, see IsAutoClass and DeclaringType. Inoltre, alcuni membri sono validi solo quando un oggetto Type rappresenta un parametro di tipo generico.In addition, some members are valid only when a Type object represents a generic type parameter. Ad esempio, vedere GetGenericTypeDefinition.For example, see GetGenericTypeDefinition.

  • Se un'istanza di Type rappresenta un tipo generico, includerà una matrice di tipi che rappresentano i parametri di tipo (per le definizioni di tipo generico) o gli argomenti di tipo (per i tipi costruiti).If an instance of Type represents a generic type, then it includes an array of types that represent the type parameters (for generic type definitions) or the type arguments (for constructed types). Questo è vero anche per un'istanza della classe MethodInfo che rappresenta un metodo generico.The same is true of an instance of the MethodInfo class that represents a generic method.

La reflection fornisce metodi di Type e MethodInfo che consentono di accedere alla matrice di parametri di tipo e stabilire se un'istanza di Type rappresenta un parametro di tipo o un tipo effettivo.Reflection provides methods of Type and MethodInfo that allow you to access the array of type parameters, and to determine whether an instance of Type represents a type parameter or an actual type.

Per un codice di esempio in cui sono illustrati i metodi indicati in questo argomento, vedere How to: Examine and Instantiate Generic Types with Reflection (Procedura: Esaminare e creare istanze di tipi generici con reflection).For example code demonstrating the methods discussed here, see How to: Examine and Instantiate Generic Types with Reflection.

Nelle considerazioni che seguono si presuppone la conoscenza della terminologia relativa ai generics, ad esempio la differenza tra argomenti e parametri di tipo e quella tra tipi costruiti aperti o chiusi.The following discussion assumes familiarity with the terminology of generics, such as the difference between type parameters and arguments and open or closed constructed types. Per altre informazioni, vedere Generics.For more information, see Generics.

Questa panoramica include le sezioni seguenti:This overview consists of the following sections:

Come stabilire se un tipo o un metodo è genericoIs This a Generic Type or Method?

Quando si esamina un tipo sconosciuto rappresentato da un'istanza di Typetramite la reflection, usare la proprietà IsGenericType per stabilire se il tipo sconosciuto è generico.When you use reflection to examine an unknown type, represented by an instance of Type, use the IsGenericType property to determine whether the unknown type is generic. Se il tipo è generico, restituisce true .It returns true if the type is generic. In modo analogo, quando si esamina un metodo sconosciuto rappresentato da un'istanza della classe MethodInfo , usare la proprietà IsGenericMethod per stabilire se il metodo è generico.Similarly, when you examine an unknown method, represented by an instance of the MethodInfo class, use the IsGenericMethod property to determine whether the method is generic.

Come stabilire se un oggetto rappresenta una definizione di metodo o di tipo genericoIs This a Generic Type or Method Definition?

Usare la proprietà IsGenericTypeDefinition per stabilire se un oggetto Type rappresenta una definizione di tipo generico e il metodo IsGenericMethodDefinition per determinare se un oggetto MethodInfo rappresenta una definizione di metodo generico.Use the IsGenericTypeDefinition property to determine whether a Type object represents a generic type definition, and use the IsGenericMethodDefinition method to determine whether a MethodInfo represents a generic method definition.

Le definizioni di metodo e di tipo generico costituiscono i modelli a partire dai quali vengono creati i tipi istanziabili.Generic type and method definitions are the templates from which instantiable types are created. I tipi generici nella libreria di classi .NET Framework, ad esempio Dictionary<TKey,TValue>, sono definizioni di tipo generico.Generic types in the .NET Framework class library, such as Dictionary<TKey,TValue>, are generic type definitions.

Come stabilire se un tipo o un metodo è aperto o chiusoIs the Type or Method Open or Closed?

Un tipo o un metodo generico è chiuso se tutti i relativi parametri di tipo, inclusi tutti i parametri di tipo di tutti i tipi di inclusione, sono stati sostituiti da tipi istanziabili.A generic type or method is closed if instantiable types have been substituted for all its type parameters, including all the type parameters of all enclosing types. È possibile creare un'istanza di un tipo generico solo se è chiuso.You can only create an instance of a generic type if it is closed. Se un tipo è aperto, la proprietà Type.ContainsGenericParameters restituisce true .The Type.ContainsGenericParameters property returns true if a type is open. Per i metodi, la stessa funzione viene eseguita dal metodo MethodBase.ContainsGenericParameters .For methods, the MethodBase.ContainsGenericParameters method performs the same function.

Torna all'inizioBack to top

Generazione di tipi generici chiusiGenerating Closed Generic Types

Dopo avere ottenuto una definizione di metodo o di tipo generico, usare il metodo MakeGenericType per creare un tipo generico chiuso oppure il metodo MakeGenericMethod per creare un oggetto MethodInfo relativo a un metodo generico chiuso.Once you have a generic type or method definition, use the MakeGenericType method to create a closed generic type or the MakeGenericMethod method to create a MethodInfo for a closed generic method.

Recupero della definizione di tipo o di metodo genericoGetting the Generic Type or Method Definition

Se è disponibile un tipo o di un metodo generico aperto che non è una definizione di tipo o di metodo generico, non è possibile crearne istanze né specificare i parametri di tipo mancanti.If you have an open generic type or method that is not a generic type or method definition, you cannot create instances of it and you cannot supply the type parameters that are missing. A questo scopo è necessario avere una definizione di tipo o di metodo generico.You must have a generic type or method definition. Usare il metodo GetGenericTypeDefinition per ottenere la definizione di tipo generico o il metodo GetGenericMethodDefinition per ottenere la definizione di metodo generico.Use the GetGenericTypeDefinition method to obtain the generic type definition or the GetGenericMethodDefinition method to obtain the generic method definition.

Ad esempio, se si ha un oggetto Type che rappresenta Dictionary<int, string> (Dictionary(Of Integer, String) in Visual Basic) e si vuole creare il tipo Dictionary<string, MyClass>, è possibile usare il metodo GetGenericTypeDefinition per ottenere un oggetto Type che rappresenta Dictionary<TKey, TValue> e quindi il metodo MakeGenericType per generare un oggetto Type che rappresenta Dictionary<int, MyClass>.For example, if you have a Type object representing Dictionary<int, string> (Dictionary(Of Integer, String) in Visual Basic) and you want to create the type Dictionary<string, MyClass>, you can use the GetGenericTypeDefinition method to get a Type representing Dictionary<TKey, TValue> and then use the MakeGenericType method to produce a Type representing Dictionary<int, MyClass>.

Per un esempio di tipo generico aperto che non è un tipo generico, vedere la sezione "Parametro di tipo o argomento di tipo" più avanti in questo argomento.For an example of an open generic type that is not a generic type, see "Type Parameter or Type Argument" later in this topic.

Torna all'inizioBack to top

Analisi degli argomenti e dei parametri di tipoExamining Type Arguments and Type Parameters

Usare il metodo Type.GetGenericArguments per ottenere una matrice di oggetti Type che rappresentano i parametri o gli argomenti di tipo di un tipo generico e il metodo MethodInfo.GetGenericArguments per eseguire la stessa operazione per un metodo generico.Use the Type.GetGenericArguments method to obtain an array of Type objects that represent the type parameters or type arguments of a generic type, and use the MethodInfo.GetGenericArguments method to do the same for a generic method.

Dopo avere stabilito che l'oggetto Type rappresenta un parametro di tipo, la reflection consentirà di ottenere altre informazioni al riguardo.Once you know that a Type object represents a type parameter, there are many additional questions reflection can answer. È possibile determinare l'origine, la posizione e i vincoli del parametro di tipo.You can determine the type parameter's source, its position, and its constraints.

Parametro di tipo o argomento di tipoType Parameter or Type Argument

Per stabilire se un determinato elemento della matrice è un parametro di tipo oppure un argomento di tipo, usare la proprietà IsGenericParameter .To determine whether a particular element of the array is a type parameter or a type argument, use the IsGenericParameter property. Se l'elemento è un parametro di tipo, la proprietà IsGenericParameter restituisce true .The IsGenericParameter property is true if the element is a type parameter.

Un tipo generico può essere aperto senza essere una definizione di tipo generico, nel qual caso presenterà sia argomenti di tipo che parametri di tipo.A generic type can be open without being a generic type definition, in which case it has a mixture of type arguments and type parameters. Ad esempio, nel codice seguente la classe D deriva da un tipo creato sostituendo il primo parametro di tipo D al secondo parametro di tipo B.For example, in the following code, class D derives from a type created by substituting the first type parameter of D for the second type parameter of B.

class B<T, U> {}  
class D<V, W> : B<int, V> {}  
Class B(Of T, U)  
End Class  
Class D(Of V, W)  
    Inherits B(Of Integer, V)  
End Class  
generic<typename T, typename U> ref class B {};  
generic<typename V, typename W> ref class D : B<int, V> {};  

Se si ottiene un oggetto Type che rappresenta D<V, W> e si usa la proprietà BaseType per recuperarne il tipo di base, il type B<int, V> risultante sarà aperto, ma non sarà una definizione di tipo generico.If you obtain a Type object representing D<V, W> and use the BaseType property to obtain its base type, the resulting type B<int, V> is open, but it is not a generic type definition.

Origine di un parametro genericoSource of a Generic Parameter

Un parametro di tipo generico può provenire dal tipo in esame, da un tipo di inclusione o da un metodo generico.A generic type parameter might come from the type you are examining, from an enclosing type, or from a generic method. È possibile determinarne l'origine nel modo seguente:You can determine the source of the generic type parameter as follows:

  • Prima di tutto, usare la proprietà DeclaringMethod per determinare se il parametro di tipo proviene da un metodo generico.First, use the DeclaringMethod property to determine whether the type parameter comes from a generic method. Se il valore della proprietà non è un riferimento Null (Nothing in Visual Basic), l'origine è un metodo generico.If the property value is not a null reference (Nothing in Visual Basic), then the source is a generic method.

  • Se l'origine non è un metodo generico, usare la proprietà DeclaringType per determinare il tipo generico a cui appartiene il parametro di tipo generico.If the source is not a generic method, use the DeclaringType property to determine the generic type the generic type parameter belongs to.

Se il parametro di tipo appartiene a un metodo generico, la proprietà DeclaringType restituisce il tipo che ha dichiarato tale metodo, che non è un'informazione rilevante.If the type parameter belongs to a generic method, the DeclaringType property returns the type that declared the generic method, which is irrelevant.

Posizione di un parametro genericoPosition of a Generic Parameter

In rare situazioni è necessario stabilire la posizione di un parametro di tipo nell'elenco dei parametri di tipo della classe dichiarante.In rare situations, it is necessary to determine the position of a type parameter in the type parameter list of its declaring class. Si supponga ad esempio di avere un oggetto Type che rappresenta il tipo B<int, V> dell'esempio precedente.For example, suppose you have a Type object representing the B<int, V> type from the preceding example. Il metodo GetGenericArguments fornisce un elenco di argomenti di tipo ed è possibile determinare l'origine del parametro V in esame usando le proprietà DeclaringMethod e DeclaringType .The GetGenericArguments method gives you a list of type arguments, and when you examine V you can use the DeclaringMethod and DeclaringType properties to discover where it comes from. È quindi possibile usare la proprietà GenericParameterPosition per determinare la posizione del parametro nell'elenco dei parametri del tipo in cui il parametro è stato definito.You can then use the GenericParameterPosition property to determine its position in the type parameter list where it was defined. In questo esempio, V si trova nella posizione 0 (zero) dell'elenco di parametri di tipo in cui è stato definito.In this example, V is at position 0 (zero) in the type parameter list where it was defined.

Vincoli di interfaccia e del tipo di baseBase Type and Interface Constraints

Usare il metodo GetGenericParameterConstraints per ottenere il vincolo del tipo di base e i vincoli di interfaccia di un parametro di tipo.Use the GetGenericParameterConstraints method to obtain the base type constraint and interface constraints of a type parameter. L'ordine degli elementi della matrice non è significativo.The order of the elements of the array is not significant. Un elemento rappresenta un vincolo di interfaccia se è un tipo di interfaccia.An element represents an interface constraint if it is an interface type.

Attributi di parametri generici:Generic Parameter Attributes

La proprietà GenericParameterAttributes ottiene un valore GenericParameterAttributes che indica la varianza (covarianza o controvarianza) e i vincoli speciali di un parametro di tipo.The GenericParameterAttributes property gets a GenericParameterAttributes value that indicates the variance (covariance or contravariance) and the special constraints of a type parameter.

Covarianza e controvarianzaCovariance and Contravariance

Per determinare se un parametro di tipo sia covariante o controvariante, applicare la maschera GenericParameterAttributes.VarianceMask al valore GenericParameterAttributes restituito dalla proprietà GenericParameterAttributes .To determine whether a type parameter is covariant or contravariant, apply the GenericParameterAttributes.VarianceMask mask to the GenericParameterAttributes value that is returned by the GenericParameterAttributes property. Se il risultato è GenericParameterAttributes.None, il parametro di tipo è invariante.If the result is GenericParameterAttributes.None, the type parameter is invariant. Vedere Covarianza e controvarianza.See Covariance and Contravariance.

Vincoli specialiSpecial Constraints

Per stabilire i vincoli speciali di un parametro di tipo, applicare la maschera GenericParameterAttributes.SpecialConstraintMask al valore GenericParameterAttributes restituito dalla proprietà GenericParameterAttributes .To determine the special constraints of a type parameter, apply the GenericParameterAttributes.SpecialConstraintMask mask to the GenericParameterAttributes value that is returned by the GenericParameterAttributes property. Se il risultato è GenericParameterAttributes.None, non sono presenti vincoli speciali.If the result is GenericParameterAttributes.None, there are no special constraints. Un parametro di tipo può essere vincolato per essere un tipo riferimento, un tipo valore non nullable e per avere un costruttore senza parametri.A type parameter can be constrained to be a reference type, to be a non-nullable value type, and to have a parameterless constructor.

Torna all'inizioBack to top

InvariantiInvariants

Per una tabella di condizioni non variabili associate a termini comuni nella reflection per tipi generici, vedere Type.IsGenericType.For a table of the invariant conditions for common terms in reflection for generic types, see Type.IsGenericType. Per altri termini correlati ai metodi generici, vedere MethodBase.IsGenericMethod.For additional terms relating to generic methods, see MethodBase.IsGenericMethod.

Torna all'inizioBack to top

TitoloTitle DescrizioneDescription
Procedura: Esaminare e creare istanze di tipi generici con reflectionHow to: Examine and Instantiate Generic Types with Reflection Mostra come usare le proprietà e i metodi di Type e MethodInfo per esaminare i tipi generici.Shows how to use the properties and methods of Type and MethodInfo to examine generic types.
GenericsGenerics Descrive la funzionalità generics con la relativa modalità di supporto in .NET Framework.Describes the generics feature and how it is supported in the .NET Framework.
Procedura: Definire un tipo generico tramite reflection emitHow to: Define a Generic Type with Reflection Emit Mostra come usare la reflection emit per generate tipi generici in assembly dinamici.Shows how to use reflection emit to generate generic types in dynamic assemblies.
Visualizzazione delle informazioni sul tipoViewing Type Information Descrive la classe Type e vengono forniti esempi di codice in cui viene descritto l'uso di Type con diverse classi di reflection per ottenere informazioni su costruttori, metodi, campi, proprietà ed eventi.Describes the Type class and provides code examples that illustrate how to use Type with various reflection classes to obtain information about constructors, methods, fields, properties, and events.