Condividi tramite


Metodi System.Type.GetType

Questo articolo fornisce osservazioni supplementari alla documentazione di riferimento per questa API.

Usare l'overload del GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean, Boolean) metodo e gli overload associati (GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>) e GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean)) per sostituire l'implementazione predefinita del GetType metodo con implementazioni più flessibili. Fornendo metodi personalizzati che risolvono i nomi dei tipi e i nomi degli assembly che li contengono, è possibile eseguire le operazioni seguenti:

  • Controllare la versione di un assembly da cui viene caricato un tipo.
  • Specificare un'altra posizione in cui cercare un nome di tipo che non include un nome di assembly.
  • Caricare assembly usando nomi di assembly parziali.
  • Restituisce sottoclassi di System.Type che non vengono create da Common Language Runtime (CLR).

Ad esempio, nella serializzazione a tolleranza di versione questo metodo consente di cercare un assembly "più adatto" usando un nome parziale. Altri overload del GetType metodo richiedono un nome di tipo qualificato dall'assembly, che include il numero di versione.

Le implementazioni alternative del sistema di tipi potrebbero dover restituire sottoclassi di System.Type che non vengono create da CLR. Tutti i tipi restituiti da altri overload del GetType metodo sono tipi di runtime.

Note sull'utilizzo

Questo overload del metodo e gli overload associati analizzano il nome di un tipo e il nome di un assembly e quindi risolvono typeName i nomi. La risoluzione del nome dell'assembly si verifica prima della risoluzione del nome del tipo, perché è necessario risolvere un nome di tipo nel contesto di un assembly.

Nota

Se non si ha familiarità con il concetto di nomi di tipi qualificati dall'assembly, vedere la AssemblyQualifiedName proprietà .

Se typeName non è un nome qualificato dall'assembly, la risoluzione dell'assembly viene ignorata. I nomi dei tipi non qualificati possono essere risolti nel contesto di mscorlib.dll/System.Private.CoreLib.dll o dell'assembly attualmente in esecuzione oppure è possibile specificare facoltativamente un assembly nel typeResolver parametro . Gli effetti dell'inclusione o dell'omissione del nome dell'assembly per diversi tipi di risoluzione dei nomi vengono visualizzati come tabella nella sezione Risoluzione dei nomi misti.

Note generali sull'utilizzo:

  • Non passare metodi a assemblyResolver o typeResolver se provengono da chiamanti sconosciuti o non attendibili. Usare solo i metodi forniti o con cui si ha dimestichezza.

    Attenzione

    L'uso di metodi di chiamanti sconosciuti o non attendibili potrebbe comportare l'elevazione dei privilegi per il codice dannoso.

  • Se si omettono i assemblyResolver parametri e/o typeResolver , il valore del throwOnError parametro viene passato ai metodi che eseguono la risoluzione predefinita.

  • Se throwOnError è true, questo metodo genera un'eccezione TypeLoadException quando typeResolver restituisce nulle quando assemblyResolverFileNotFoundException restituisce null.

  • Questo metodo non intercetta le eccezioni generate da assemblyResolver e typeResolver. L'utente è responsabile di tutte le eccezioni generate dai metodi del sistema di risoluzione.

Risolvere gli assembly

Il assemblyResolver metodo riceve un AssemblyName oggetto, generato analizzando il nome dell'assembly stringa incluso in typeName. Se typeName non contiene un nome di assembly, assemblyResolver non viene chiamato e null viene passato a typeResolver.

Se assemblyResolver non viene fornito, per individuare l'assembly viene usato il probe di assembly standard. Se assemblyResolver viene specificato, il GetType metodo non esegue il probe standard. In tal caso, è necessario assicurarsi che sia assemblyResolver possibile gestire tutti gli assembly passati.

Il assemblyResolver metodo deve restituire null se l'assembly non può essere risolto. Se assemblyResolver restituisce null, typeResolver non viene chiamato e non viene eseguita alcuna ulteriore elaborazione; inoltre, se throwOnError è true, viene generata un'eccezione FileNotFoundException .

Se l'oggetto AssemblyName passato a assemblyResolver è un nome parziale, una o più parti sono null. Ad esempio, se non ha una versione, la Version proprietà è null. Se la Version proprietà , la CultureInfo proprietà e il GetPublicKeyToken metodo restituiscono nulltutti , è stato fornito solo il nome semplice dell'assembly. Il assemblyResolver metodo può utilizzare o ignorare tutte le parti del nome dell'assembly.

Gli effetti delle diverse opzioni di risoluzione degli assembly vengono visualizzati come tabella nella sezione Risoluzione dei nomi misti per i nomi di tipi semplici e qualificati per assembly.

Risolvere i tipi

Se typeName non specifica un nome di assembly, typeResolver viene sempre chiamato . Se typeName specifica un nome di assembly, typeResolver viene chiamato solo quando il nome dell'assembly viene risolto correttamente. Se assemblyResolver o il probe di assembly standard restituisce null, typeResolver non viene chiamato .

Il typeResolver metodo riceve tre argomenti:

  • Assembly da cercare o null se typeName non contiene un nome di assembly.
  • Nome semplice del tipo. Nel caso di un tipo annidato, si tratta del tipo contenitore più esterno. Nel caso di un tipo generico, si tratta del nome semplice del tipo generico.
  • Valore booleano che si verifica true se il caso dei nomi dei tipi deve essere ignorato.

L'implementazione determina la modalità di utilizzo di questi argomenti. Il typeResolver metodo deve restituire null se non è in grado di risolvere il tipo. Se restituisce null e throwOnError è true, questo overload di GetType genera un oggetto TypeLoadException.typeResolver

Gli effetti delle diverse opzioni di risoluzione dei tipi vengono visualizzati come tabella nella sezione Risoluzione dei nomi misti per i nomi di tipi semplici e qualificati dall'assembly.

Risolvere i tipi annidati

Se typeName è un tipo annidato, viene passato solo il nome del tipo contenitore più esterno a typeResolver. Quando typeResolver restituisce questo tipo, il GetNestedType metodo viene chiamato in modo ricorsivo fino a quando non viene risolto il tipo annidato più interno.

Risolvere i tipi generici

Viene GetType chiamato in modo ricorsivo per risolvere i tipi generici: prima di tutto per risolvere il tipo generico stesso e quindi risolvere i relativi argomenti di tipo. Se un argomento di tipo è generico, GetType viene chiamato in modo ricorsivo per risolvere i relativi argomenti di tipo e così via.

La combinazione di assemblyResolver e typeResolver che fornisci deve essere in grado di risolvere tutti i livelli di questa ricorsione. Si supponga, ad esempio, di fornire un oggetto assemblyResolver che controlla il caricamento di MyAssembly. Si supponga di voler risolvere il tipo Dictionary<string, MyType> generico (Dictionary(Of String, MyType) in Visual Basic). È possibile passare il nome di tipo generico seguente:

"System.Collections.Generic.Dictionary`2[System.String,[MyNamespace.MyType, MyAssembly]]"

Si noti che MyType è l'unico argomento di tipo qualificato dall'assembly. I nomi delle Dictionary<TKey,TValue> classi e String non sono qualificati per assembly. Deve typeResolver essere in grado di gestire un assembly o null, perché riceverà null per Dictionary<TKey,TValue> e String. Può gestire questo caso chiamando un overload del GetType metodo che accetta una stringa, perché entrambi i nomi dei tipi non qualificati si trovano in mscorlib.dll/System.Private.CoreLib.dll:

Type t = Type.GetType(test,
                      (aName) => aName.Name == "MyAssembly" ?
                          Assembly.LoadFrom(@".\MyPath\v5.0\MyAssembly.dll") : null,
                      (assem, name, ignore) => assem == null ?
                          Type.GetType(name, false, ignore) :
                              assem.GetType(name, false, ignore)
                     );
let t =
    Type.GetType(test,
        (fun aName ->
            if aName.Name = "MyAssembly" then
                Assembly.LoadFrom @".\MyPath\v5.0\MyAssembly.dll"
            else null),
        fun assem name ignr ->
            if assem = null then
                Type.GetType(name, false, ignr)
            else
                assem.GetType(name, false, ignr))

Il assemblyResolver metodo non viene chiamato per il tipo di dizionario e il tipo stringa, perché tali nomi di tipo non sono qualificati dall'assembly.

Si supponga ora che invece di , il primo tipo di System.Stringargomento generico è YourType, da YourAssembly:

"System.Collections.Generic.Dictionary`2[[YourNamespace.YourType, YourAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null], [MyNamespace.MyType, MyAssembly]]"

Poiché questo assembly non è né mscorlib.dll/System.Private.CoreLib.dll né l'assembly attualmente in esecuzione, non è possibile risolvere YourType senza un nome completo dell'assembly. assemblyResolve Poiché verrà chiamato in modo ricorsivo, deve essere in grado di gestire questo caso. Anziché restituire null per assembly diversi da MyAssembly, esegue ora un caricamento di assembly usando l'oggetto fornito AssemblyName .

Type t2 = Type.GetType(test,
                       (aName) => aName.Name == "MyAssembly" ?
                           Assembly.LoadFrom(@".\MyPath\v5.0\MyAssembly.dll") :
                           Assembly.Load(aName),
                       (assem, name, ignore) => assem == null ?
                           Type.GetType(name, false, ignore) :
                               assem.GetType(name, false, ignore), true
                      );
let t2 =
    Type.GetType(test,
        (fun aName ->
            if aName.Name = "MyAssembly" then
                Assembly.LoadFrom @".\MyPath\v5.0\MyAssembly.dll"
            else Assembly.Load aName),
        (fun assem name ignr ->
            if assem = null then
                Type.GetType(name, false, ignr)
            else
                assem.GetType(name, false, ignr)), true)

Risolvere i nomi dei tipi con caratteri speciali

Alcuni caratteri hanno significati speciali nei nomi qualificati dall'assembly. Se un nome di tipo semplice contiene questi caratteri, i caratteri causano errori di analisi quando il nome semplice fa parte di un nome qualificato dall'assembly. Per evitare gli errori di analisi, è necessario eseguire l'escape dei caratteri speciali con una barra rovesciata prima di poter passare il nome completo dell'assembly al GetType metodo . Ad esempio, se un tipo è denominato Strange]Type, il carattere di escape deve essere aggiunto prima della parentesi quadrata come indicato di seguito: Strange\]Type.

Nota

I nomi con tali caratteri speciali non possono essere creati in Visual Basic o C#, ma possono essere creati usando common intermediate language (CIL) o creando assembly dinamici.

Nella tabella seguente vengono illustrati i caratteri speciali per i nomi dei tipi.

Carattere Significato
, (virgola) Delimitatore per i nomi qualificati dall'assembly.
[] (parentesi quadre) Come coppia di suffissi, indica un tipo di matrice; come coppia delimitatore, racchiude gli elenchi di argomenti generici e i nomi completi di assembly.
& (e commerciale) Come suffisso, indica che un tipo è un tipo riferimento.
* (asterisco) Come suffisso, indica che un tipo è un tipo di puntatore.
+ (più) Delimitatore per i tipi annidati.
\ (barra rovesciata) Carattere di escape.

Proprietà come AssemblyQualifiedName la restituzione di stringhe di escape corrette. È necessario passare correttamente stringhe di escape al GetType metodo . A sua volta, il GetType metodo passa nomi di escape corretti a typeResolver e ai metodi di risoluzione dei tipi predefiniti. Se è necessario confrontare un nome con un nome senza caratteri di escape in typeResolver, è necessario rimuovere i caratteri di escape.

Risoluzione dei nomi misti

La tabella seguente riepiloga le interazioni tra assemblyResolver, typeResolvere la risoluzione dei nomi predefinita, per tutte le combinazioni di nome di tipo e nome dell'assembly in typeName:

Contenuto del nome del tipo Metodo resolver di assembly Metodo resolver di tipi Risultato
tipo, assembly Null Null Equivale a chiamare l'overload del Type.GetType(String, Boolean, Boolean) metodo.
tipo, assembly Fornito Null assemblyResolver restituisce l'assembly o restituisce null se non è in grado di risolvere l'assembly. Se l'assembly viene risolto, viene utilizzato l'overload Assembly.GetType(String, Boolean, Boolean) del metodo per caricare il tipo dall'assembly. In caso contrario, non viene eseguito alcun tentativo di risolvere il tipo.
tipo, assembly Null Fornito Equivale a convertire il nome dell'assembly in un AssemblyName oggetto e a chiamare l'overload del Assembly.Load(AssemblyName) metodo per ottenere l'assembly. Se l'assembly viene risolto, viene passato a typeResolver; in caso contrario, typeResolver non viene chiamato e non viene chiamato alcun ulteriore tentativo di risolvere il tipo.
tipo, assembly Fornito Fornito assemblyResolver restituisce l'assembly o restituisce null se non è in grado di risolvere l'assembly. Se l'assembly viene risolto, viene passato a typeResolver; in caso contrario, typeResolver non viene chiamato e non viene chiamato alcun ulteriore tentativo di risolvere il tipo.
type Null, fornito Null Equivale a chiamare l'overload del Type.GetType(String, Boolean, Boolean) metodo. Poiché il nome dell'assembly non viene specificato, vengono eseguite ricerche solo mscorlib.dll/System.Private.CoreLib.dll e l'assembly attualmente in esecuzione. Se assemblyResolver viene specificato, viene ignorato.
type Null, fornito Fornito typeResolver viene chiamato e null viene passato per l'assembly. typeResolver può fornire un tipo da qualsiasi assembly, inclusi gli assembly caricati per lo scopo. Se assemblyResolver viene specificato, viene ignorato.
assembly Null, fornito Null, fornito Viene FileLoadException generata un'eccezione perché il nome dell'assembly viene analizzato come se fosse un nome di tipo qualificato dall'assembly. In questo modo viene restituito un nome di assembly non valido.