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
otypeResolver
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/otypeResolver
, il valore delthrowOnError
parametro viene passato ai metodi che eseguono la risoluzione predefinita.Se
throwOnError
ètrue
, questo metodo genera un'eccezione TypeLoadException quandotypeResolver
restituiscenull
e quandoassemblyResolver
FileNotFoundException restituiscenull
.Questo metodo non intercetta le eccezioni generate da
assemblyResolver
etypeResolver
. 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 null
tutti , è 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
setypeName
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.String
argomento 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
, typeResolver
e 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. |