Méthodes System.Type.GetType

Cet article vous offre des remarques complémentaires à la documentation de référence pour cette API.

Utilisez la GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean, Boolean) surcharge de méthode et ses surcharges associées (GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>) et GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean)) pour remplacer l’implémentation par défaut de la GetType méthode par des implémentations plus flexibles. En fournissant vos propres méthodes qui résolvent les noms de type et les noms des assemblys qui les contiennent, vous pouvez effectuer les opérations suivantes :

  • Contrôlez la version d’un assembly à partir de laquelle un type est chargé.
  • Fournissez un autre emplacement pour rechercher un nom de type qui n’inclut pas de nom d’assembly.
  • Chargez des assemblys à l’aide de noms d’assembly partiels.
  • Retourne les sous-classes de System.Type celles qui ne sont pas créées par le Common Language Runtime (CLR).

Par exemple, dans la sérialisation à tolérance de version, cette méthode vous permet de rechercher un assembly « meilleur ajustement » à l’aide d’un nom partiel. D’autres surcharges de la GetType méthode nécessitent un nom de type qualifié d’assembly, qui inclut le numéro de version.

D’autres implémentations du système de type peuvent avoir besoin de retourner des sous-classes de System.Type celles qui ne sont pas créées par le CLR ; tous les types retournés par d’autres surcharges de la GetType méthode sont des types d’exécution.

Notes d’utilisation

Cette surcharge de méthode et ses surcharges associées analysent typeName le nom d’un type et le nom d’un assembly, puis résolvent les noms. La résolution du nom de l’assembly se produit avant la résolution du nom de type, car un nom de type doit être résolu dans le contexte d’un assembly.

Remarque

Si vous ne connaissez pas le concept de noms de types qualifiés d’assembly, consultez la AssemblyQualifiedName propriété.

Si typeName ce n’est pas un nom qualifié pour l’assembly, la résolution d’assembly est ignorée. Les noms de types non qualifiés peuvent être résolus dans le contexte de mscorlib.dll/System.Private.CoreLib.dll ou de l’assembly en cours d’exécution, ou vous pouvez éventuellement fournir un assembly dans le typeResolver paramètre. Les effets de l’inclusion ou de l’omission du nom d’assembly pour différents types de résolution de noms sont affichés sous forme de tableau dans la section Résolution de noms mixte.

Notes d’utilisation générales :

  • Ne transmettez pas de méthodes à assemblyResolver ou typeResolver s’ils proviennent d’appelants inconnus ou non approuvés. Utilisez uniquement les méthodes que vous fournissez ou avec lesquelles vous êtes familiarisé.

    Attention

    L’utilisation de méthodes provenant d’appelants inconnus ou non approuvés peut entraîner une élévation de privilèges pour le code malveillant.

  • Si vous omettez les assemblyResolver paramètres et/ou typeResolver les paramètres, la valeur du throwOnError paramètre est transmise aux méthodes qui effectuent la résolution par défaut.

  • Si throwOnError c’est truele cas, cette méthode lève une TypeLoadException valeur de retour nulltypeResolver et une FileNotFoundException valeur quand assemblyResolver elle est retournéenull.

  • Cette méthode n’intercepte pas les exceptions levées par assemblyResolver et typeResolver. Vous êtes responsable des exceptions levées par les méthodes de programme de résolution.

Résoudre les assemblys

La assemblyResolver méthode reçoit un AssemblyName objet, qui est produit en analysant le nom de l’assembly de chaîne inclus dans typeName. S’il typeName ne contient pas de nom d’assembly, assemblyResolver n’est pas appelé et null est passé à typeResolver.

S’il assemblyResolver n’est pas fourni, la détection d’assembly standard est utilisée pour localiser l’assembly. Si assemblyResolver elle est fournie, la GetType méthode n’effectue pas de sondage standard ; dans ce cas, vous devez vous assurer que vous assemblyResolver pouvez gérer tous les assemblys que vous lui transmettez.

La assemblyResolver méthode doit retourner null si l’assembly ne peut pas être résolu. Si assemblyResolver retourne null, typeResolver n’est pas appelé et aucun traitement supplémentaire ne se produit ; en outre, si throwOnError c’est truele cas, un FileNotFoundException est levée.

Si le AssemblyName nom passé assemblyResolver est un nom partiel, une ou plusieurs de ses parties sont null. Par exemple, s’il n’a pas de version, la Version propriété est null. Si la Version propriété, la CultureInfo propriété et la GetPublicKeyToken méthode retournent nulltous, seul le nom simple de l’assembly a été fourni. La assemblyResolver méthode peut utiliser ou ignorer toutes les parties du nom de l’assembly.

Les effets des différentes options de résolution d’assembly sont affichés sous forme de tableau dans la section Résolution de noms mixte, pour les noms de types simples et qualifiés d’assembly.

Résoudre les types

Si typeName aucun nom d’assembly n’est spécifié, typeResolver il est toujours appelé. Si typeName elle spécifie un nom d’assembly, typeResolver elle est appelée uniquement lorsque le nom de l’assembly est résolu avec succès. Si assemblyResolver ou le sondage d’assembly standard retourne null, typeResolver n’est pas appelé.

La typeResolver méthode reçoit trois arguments :

  • Assembly à rechercher ou null s’il typeName ne contient pas de nom d’assembly.
  • Nom simple du type. Dans le cas d’un type imbriqué, il s’agit du type contenant le plus externe. Dans le cas d’un type générique, il s’agit du nom simple du type générique.
  • Valeur booléenne qui est true si le cas des noms de types doit être ignoré.

L’implémentation détermine la façon dont ces arguments sont utilisés. La typeResolver méthode doit retourner null si elle ne peut pas résoudre le type. Si typeResolver elle est retournée null et throwOnError est true, cette surcharge de GetType lève un TypeLoadException.

Les effets des différentes options de résolution de type sont affichés sous forme de tableau dans la section Résolution de noms mixte, pour les noms de types simples et qualifiés d’assembly.

Résoudre les types imbriqués

S’il typeName s’agit d’un type imbriqué, seul le nom du type contenant le plus externe est passé à typeResolver. Lorsque typeResolver cette propriété retourne ce type, la GetNestedType méthode est appelée de manière récursive jusqu’à ce que le type imbriqué le plus interne ait été résolu.

Résoudre les types génériques

Il GetType est appelé de manière récursive pour résoudre les types génériques : commencez par résoudre le type générique lui-même, puis pour résoudre ses arguments de type. Si un argument de type est générique, GetType est appelé de manière récursive pour résoudre ses arguments de type, et ainsi de suite.

La combinaison de assemblyResolver et typeResolver de ce que vous fournissez doit être capable de résoudre tous les niveaux de cette récursivité. Par exemple, supposons que vous fournissez un assemblyResolver contrôle du chargement de MyAssembly. Supposons que vous souhaitez résoudre le type Dictionary<string, MyType> générique (Dictionary(Of String, MyType) en Visual Basic). Vous pouvez passer le nom de type générique suivant :

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

Notez qu’il MyType s’agit du seul argument de type qualifié d’assembly. Les noms des classes et String des Dictionary<TKey,TValue> classes ne sont pas qualifiés par l’assembly. Votre typeResolver doit être en mesure de gérer un assembly ou null, car il recevra null pour Dictionary<TKey,TValue> et String. Il peut gérer ce cas en appelant une surcharge de la GetType méthode qui accepte une chaîne, car les deux noms de types non qualifiés se trouvent dans 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))

La assemblyResolver méthode n’est pas appelée pour le type de dictionnaire et le type de chaîne, car ces noms de types ne sont pas qualifiés par l’assembly.

Supposons maintenant que, au lieu de , le premier type d’argument System.Stringgénérique est YourType, à partir de YourAssembly:

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

Étant donné que cet assembly n’est ni mscorlib.dll/System.Private.CoreLib.dll ni l’assembly en cours d’exécution, vous ne pouvez pas résoudre YourType sans nom qualifié d’assembly. Étant donné que votre assemblyResolve sera appelé de manière récursive, il doit être en mesure de gérer ce cas. Au lieu de retourner null des assemblys autres que MyAssembly, il effectue désormais une charge d’assembly à l’aide de l’objet fourni 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)

Résoudre les noms de types avec des caractères spéciaux

Certains caractères ont des significations spéciales dans les noms qualifiés d’assembly. Si un nom de type simple contient ces caractères, les caractères provoquent des erreurs d’analyse lorsque le nom simple fait partie d’un nom qualifié d’assembly. Pour éviter les erreurs d’analyse, vous devez échapper aux caractères spéciaux avec une barre oblique inverse avant de pouvoir passer le nom qualifié d’assembly à la GetType méthode. Par exemple, si un type est nommé Strange]Type, le caractère d’échappement doit être ajouté devant le crochet comme suit : Strange\]Type.

Remarque

Les noms avec ces caractères spéciaux ne peuvent pas être créés en Visual Basic ou C#, mais peuvent être créés à l’aide du langage intermédiaire commun (CIL) ou en émettant des assemblys dynamiques.

Le tableau suivant présente les caractères spéciaux pour les noms de types.

Caractère Signification
, (virgule) Délimiteur pour les noms qualifiés d’assembly.
[] (crochets) En tant que paire de suffixes, indique un type de tableau ; en tant que paire délimiteur, place les listes d’arguments génériques et les noms qualifiés d’assembly.
& (esperluette) En tant que suffixe, indique qu’un type est un type de référence.
* (astérisque) En tant que suffixe, indique qu’un type est un type de pointeur.
+ (plus) Délimiteur pour les types imbriqués.
\ (barre oblique inverse) Caractère d’échappement.

Propriétés telles que AssemblyQualifiedName le retour des chaînes échappées correctement. Vous devez passer correctement les chaînes d’échappement à la GetType méthode. À son tour, la GetType méthode transmet les noms correctement échappés aux typeResolver méthodes de résolution de type par défaut et à celle des méthodes de résolution de type par défaut. Si vous devez comparer un nom à un nom non échapé, typeResolvervous devez supprimer les caractères d’échappement.

Résolution de noms mixte

Le tableau suivant récapitule les interactions entre assemblyResolver, typeResolveret la résolution de noms par défaut, pour toutes les combinaisons de noms de type et de nom d’assembly dans typeName:

Contenu du nom de type Méthode de résolution d’assembly Méthode de programme de résolution de type Result
type, assembly null null Équivaut à appeler la surcharge de méthode Type.GetType(String, Boolean, Boolean) .
type, assembly fourni par null assemblyResolver retourne l’assembly ou retourne null s’il ne peut pas résoudre l’assembly. Si l’assembly est résolu, la Assembly.GetType(String, Boolean, Boolean) surcharge de méthode est utilisée pour charger le type à partir de l’assembly ; sinon, il n’existe aucune tentative de résolution du type.
type, assembly null fourni par Équivaut à convertir le nom de l’assembly en objet AssemblyName et à appeler la Assembly.Load(AssemblyName) surcharge de méthode pour obtenir l’assembly. Si l’assembly est résolu, il est passé à typeResolver; sinon, typeResolver n’est pas appelé et il n’y a pas d’autre tentative de résolution du type.
type, assembly fourni par fourni par assemblyResolver retourne l’assembly ou retourne null s’il ne peut pas résoudre l’assembly. Si l’assembly est résolu, il est passé à typeResolver; sinon, typeResolver n’est pas appelé et il n’y a pas d’autre tentative de résolution du type.
type Null, fourni null Équivaut à appeler la surcharge de méthode Type.GetType(String, Boolean, Boolean) . Étant donné que le nom de l’assembly n’est pas fourni, seuls mscorlib.dll/System.Private.CoreLib.dll et l’assembly en cours d’exécution sont recherchés. Si assemblyResolver elle est fournie, elle est ignorée.
type Null, fourni fourni par typeResolver est appelé et null est passé pour l’assembly. typeResolver peut fournir un type à partir de n’importe quel assembly, y compris les assemblys qu’il charge à des fins. Si assemblyResolver elle est fournie, elle est ignorée.
assembly Null, fourni Null, fourni A FileLoadException est levée, car le nom de l’assembly est analysé comme s’il s’agissait d’un nom de type qualifié d’assembly. Cela entraîne un nom d’assembly non valide.