Freigeben über


System.Type.GetType-Methoden

Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.

Verwenden Sie die GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean, Boolean) Methodenüberladung und die damit verbundenen Überladungen (GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>) und GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean)) um die Standardimplementierung der GetType Methode durch flexiblere Implementierungen zu ersetzen. Indem Sie eigene Methoden bereitstellen, mit denen Typnamen und die Namen der Assemblys aufgelöst werden, die sie enthalten, können Sie die folgenden Aktionen ausführen:

  • Steuern Sie, aus welcher Version einer Assembly ein Typ geladen wird.
  • Geben Sie einen weiteren Ort an, um nach einem Typnamen zu suchen, der keinen Assembly-Namen enthält.
  • Laden Sie Assemblys unter Verwendung von Teilbaugruppennamen.
  • Gibt Unterklassen von System.Type zurück, die nicht von der Common Language Runtime (CLR) erzeugt werden.

In der versionstoleranten Serialisierung können Sie z. B. mithilfe eines Teilnamens nach einer "am besten geeigneten" Assembly suchen. Andere Überladungen der GetType-Methode erfordern einen assembly-qualifizierten Typnamen, der die Versionsnummer enthält.

Alternative Implementierungen des Typsystems müssen möglicherweise Unterklassen zurückgeben, die nicht vom CLR erstellt wurden. Alle Typen, die von anderen Überladungen der System.Type Methode zurückgegeben werden, sind Typen zur Laufzeit.

Verwendungshinweise

Diese Methodenüberladung und ihre zugehörigen Überladungen analysieren typeName in den Namen eines Typs und den Namen einer Assembly und lösen die Namen dann auf. Die Auflösung des Assemblynamens erfolgt vor der Auflösung des Typnamens, da ein Typname im Kontext einer Assembly aufgelöst werden muss.

Hinweis

Wenn Sie mit dem Konzept der assembly-qualifizierten Typnamen nicht vertraut sind, lesen Sie die Eigenschaft AssemblyQualifiedName .

Wenn typeName kein Assembly-qualifizierter Name ist, wird die Assembly-Auflösung übersprungen. Nicht qualifizierte Typnamen können im Kontext von mscorlib.dll/System.Private.CoreLib.dll oder der derzeit ausgeführten Assembly aufgelöst werden, oder Sie können optional eine Assembly im typeResolver Parameter bereitstellen. Die Auswirkungen des Einbeziehens oder Weglassens des Assembly-Namens für verschiedene Arten der Namensauflösung werden in einer Tabelle im Abschnitt Mixed name resolution angezeigt.

Allgemeine Nutzungshinweise:

  • Übergeben Sie keine Methoden an assemblyResolver oder typeResolver wenn sie von unbekannten oder nicht vertrauenswürdigen Aufrufen stammen. Verwenden Sie nur Methoden, die Sie bereitstellen oder mit denen Sie vertraut sind.

    Vorsicht

    Die Verwendung von Methoden durch unbekannte oder nicht vertrauenswürdige Anrufer kann zu einer Privilegienerhöhung für bösartigen Code führen.

  • Wenn Sie die assemblyResolver Und/oder typeResolver Parameter weglassen, wird der Wert des throwOnError Parameters an die Methoden übergeben, die die Standardauflösung ausführen.

  • Wenn throwOnErrortrue ist, löst diese Methode ein TypeLoadException aus, wenn typeResolvernull zurückgegeben wird, und ein FileNotFoundException , wenn assemblyResolvernull zurückgegeben wird.

  • Diese Methode fängt keine Ausnahmen ab, die von assemblyResolver und typeResolver geworfen werden. Sie sind für alle Ausnahmen verantwortlich, die von den Resolver-Methoden ausgelöst werden.

Assemblys auflösen

Die assemblyResolver Methode empfängt ein AssemblyName Objekt, das durch analysieren des Zeichenfolgenassemblynamens erzeugt wird, der in typeNameenthalten ist. Wenn typeName keinen Assemblynamen enthält, wird assemblyResolver nicht aufgerufen und null wird an typeResolver übergeben.

Wenn assemblyResolver nicht mitgeliefert wird, wird der Standard-Assembly-Test verwendet, um die Assembly zu lokalisieren. Wenn assemblyResolver bereitgestellt wird, führt die GetType Methode keine Standardprüfung durch. In diesem Fall müssen Sie sicherstellen, dass Ihre assemblyResolver alle Assemblies verarbeiten kann, die Sie an assemblyResolver übergeben.

Die assemblyResolver Methode sollte null zurückgeben, wenn die Assembly nicht aufgelöst werden kann. Wenn assemblyResolvernull zurückgibt, wird typeResolver nicht aufgerufen, und es erfolgt keine weitere Verarbeitung. Zusätzlich, wenn throwOnErrortrue ist, wird eine FileNotFoundException ausgelöst.

Wenn das AssemblyName, das an assemblyResolver übergeben wird, ein Teilname ist, sind ein oder mehrere seiner Teile null. Zum Beispiel, wenn es keine Version aufweist, ist die Version-Eigenschaft null. Wenn die Version Eigenschaft, die CultureInfo Eigenschaft und die GetPublicKeyToken Methode alle null zurückgeben, dann wurde nur der einfache Name der Assembly angegeben. Die assemblyResolver Methode kann alle Teile des Assemblynamens verwenden oder ignorieren.

Die Effekte verschiedener Assemblyauflösungsoptionen werden als Tabelle im Abschnitt " Gemischte Namensauflösung " für einfache und assemblyqualifizierte Typennamen angezeigt.

Typen auflösen

Wenn typeName kein Assemblyname angegeben wird, typeResolver wird immer aufgerufen. Wenn typeName einen Assembly-Namen angibt, wird typeResolver nur aufgerufen, wenn der Assembly-Name erfolgreich aufgelöst wurde. Wenn assemblyResolver oder das Standardassembly-Probing null zurückgibt, wird typeResolver nicht aufgerufen.

Die typeResolver Methode empfängt drei Argumente:

  • Die zu durchsuchende Assembly oder null, wenn typeName keinen Assembly-Namen aufweist.
  • Der einfache Name des Typs. Im Falle eines verschachtelten Typs ist dies der äußerste enthaltende Typ. Im Fall eines generischen Typs ist dies der einfache Name des generischen Typs.
  • Ein boolescher Wert, der true ist, wenn die Groß-/Kleinschreibung von Typnamen ignoriert werden soll.

Die Implementierung bestimmt, wie diese Argumente verwendet werden. Die Methode typeResolver sollte null zurückgeben, wenn der Typ nicht aufgelöst werden kann. Wenn typeResolvernull zurückgibt und throwOnErrortrue ist, löst diese Überladung von GetType ein TypeLoadExceptionaus.

Die Effekte verschiedener Typenauflösungsoptionen werden als Tabelle im Abschnitt " Gemischte Namensauflösung " für einfache und assemblyqualifizierte Typennamen angezeigt.

Verschachtelte Typen auflösen

Wenn typeName ein verschachtelter Typ ist, wird nur der Name des äußersten enthaltenen Typs an typeResolver übergeben. Wenn typeResolver dieser Typ zurückgegeben wird, wird die GetNestedType Methode rekursiv aufgerufen, bis der innerste geschachtelte Typ aufgelöst wurde.

Generische Typen auflösen

Dies GetType wird rekursiv aufgerufen, um generische Typen aufzulösen: Zuerst zum Auflösen des generischen Typs selbst und dann zum Auflösen der Typargumente. Wenn ein Typargument generisch ist, wird GetType rekursiv aufgerufen, um seine Typargumente aufzulösen, und so weiter.

Die Kombination von assemblyResolver und typeResolver, die Sie bereitstellen, muss imstande sein, alle Ebenen dieser Rekursion zu bewältigen. Zum Beispiel, nehmen wir an, Sie liefern ein assemblyResolver, das das Laden von MyAssembly steuert. Angenommen, Sie möchten den generischen Typ Dictionary<string, MyType> auflösen (Dictionary(Of String, MyType) in Visual Basic). Sie können den folgenden generischen Typnamen übergeben:

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

Beachten Sie, dass MyType das einzige assembly-qualifizierte Typargument ist. Die Namen der Klassen Dictionary<TKey,TValue> und String sind nicht assembly-qualifiziert. Ihr typeResolver muss in der Lage sein, entweder eine Assembly oder null zu verarbeiten, da es null für Dictionary<TKey,TValue> und Stringempfangen wird. Er kann diesen Fall behandeln, indem er eine Überladung der Methode GetType aufruft, die eine Zeichenkette annimmt, da beide unqualifizierten Typnamen in mscorlib.dll/System.Private.CoreLib.dll enthalten sind:

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))

Die assemblyResolver Methode wird nicht für den Wörterbuchtyp und den Zeichenfolgentyp aufgerufen, da diese Typnamen nicht assemblyfähig sind.

Nehmen wir nun an, dass statt System.String der erste generische Argumenttyp YourType ist, von YourAssembly:

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

Da diese Assembly weder mscorlib.dll/System.Private.CoreLib.dll noch die derzeit ausgeführte Assembly ist, können Sie YourType nicht ohne einen assembly-qualifizierten Namen auflösen. Da Ihr assemblyResolve rekursiv aufgerufen wird, muss er in der Lage sein, diesen Fall zu behandeln. Anstatt null für andere Assemblies als MyAssembly zurückzugeben, führt es jetzt eine Assembly-Ladung unter Verwendung des übergebenen AssemblyName-Objekts durch.

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)

Auflösen von Typnamen mit Sonderzeichen

Bestimmte Zeichen haben in assembly-qualifizierten Namen eine besondere Bedeutung. Wenn diese Zeichen in einem einfachen Typnamen enthalten sind, verursachen sie Parse-Fehler, wenn der einfache Name Teil eines assembly-qualifizierten Namens ist. Um Parsing-Fehler zu vermeiden, müssen Sie die Sonderzeichen mit einem Backslash entschlüsseln, bevor Sie den assembly-qualifizierten Namen an die Methode GetType übergeben können. Wenn beispielsweise ein Typ benannt Strange]Typeist, muss das Escapezeichen vor der eckigen Klammer wie folgt hinzugefügt werden: Strange\]Type

Hinweis

Namen mit solchen Sonderzeichen können in Visual Basic oder C# nicht erstellt werden, können aber mithilfe allgemeiner Zwischensprache (CIL) oder durch Senden dynamischer Assemblys erstellt werden.

In der folgenden Tabelle sind die Sonderzeichen für Typnamen aufgeführt.

Charakter Bedeutung
, (Komma) Trennzeichen für assembly-qualifizierte Namen.
[] (eckige Klammern) Gibt als Suffixpaar einen Arraytyp an; als Trennzeichenpaar schließt generische Argumentlisten und assemblyqualifizierte Namen ein.
& (kaufmännisches Und) Gibt als Suffix an, dass ein Typ ein Verweistyp ist.
* (Stern) Gibt als Suffix an, dass ein Typ ein Zeigertyp ist.
+ (plus) Begrenzungszeichen für verschachtelte Typen.
\ (umgekehrter Schrägstrich) Escapezeichen.

Eigenschaften wie AssemblyQualifiedName geben korrekt escaped Zeichenfolgen zurück. Sie müssen korrekt escaped Zeichenfolgen an die Methode GetType übergeben. Im Gegenzug übergibt die Methode GetType korrekt escaped Namen an typeResolver und an die Standardmethoden zur Typauflösung. Wenn Sie einen Namen mit einem Namen ohne Escape-Zeichen in typeResolver vergleichen müssen, müssen Sie die Escape-Zeichen entfernen.

Gemischte Namensauflösung

Die folgende Tabelle fasst die Wechselwirkungen zwischen assemblyResolver, typeResolver und der Standard-Namensauflösung für alle Kombinationen von Typname und Assembly-Name in typeName zusammen:

Inhalt des Typnamens Assembly-Resolver-Methode Typauflöser-Methode Ergebnis
Typ, Baugruppe NULL NULL Entspricht dem Aufruf der Überladung der Methode Type.GetType(String, Boolean, Boolean) .
Typ, Baugruppe bereitgestellt NULL assemblyResolver gibt die Assembly zurück oder gibt zurück null , wenn sie die Assembly nicht auflösen kann. Wenn die Assembly aufgelöst wird, wird die Assembly.GetType(String, Boolean, Boolean) Methodenüberladung verwendet, um den Typ aus der Assembly zu laden. Andernfalls wird kein Versuch unternommen, den Typ aufzulösen.
Typ, Baugruppe NULL bereitgestellt Entspricht dem Konvertieren des Assemblynamens in ein AssemblyName Objekt und Aufrufen der Assembly.Load(AssemblyName) Methodenüberladung zum Abrufen der Assembly. Wenn die Assembly aufgelöst wird, wird sie an typeResolver übergeben; andernfalls wird typeResolver nicht aufgerufen, und es wird kein weiterer Versuch unternommen, den Typ aufzulösen.
Typ, Baugruppe bereitgestellt bereitgestellt assemblyResolver gibt die Assembly zurück oder gibt zurück null , wenn sie die Assembly nicht auflösen kann. Wenn die Assembly aufgelöst wird, wird sie an typeResolver übergeben; andernfalls wird typeResolver nicht aufgerufen, und es wird kein weiterer Versuch unternommen, den Typ aufzulösen.
Typ null, vorausgesetzt NULL Entspricht dem Aufruf der Überladung der Methode Type.GetType(String, Boolean, Boolean) . Da der Assemblyname nicht angegeben wird, werden nur mscorlib.dll/System.Private.CoreLib.dll und die derzeit ausgeführte Assembly durchsucht. Wenn assemblyResolver angegeben ist, wird es ignoriert.
Typ null, vorausgesetzt bereitgestellt typeResolver wird aufgerufen, und null wird für die Assembly übergeben. typeResolver kann einen Typ aus einer beliebigen Assembly bereitstellen, einschließlich Assemblies, die es für diesen Zweck lädt. Wenn assemblyResolver angegeben ist, wird es ignoriert.
Montage null, vorausgesetzt null, vorausgesetzt Es wird ein FileLoadException ausgelöst, da der Assembly-Name geparst wird, als wäre er ein assembly-qualifizierter Typname. Dies führt zu einem ungültigen Assembly-Namen.