2016-06-12 9 views
1

Nach the documentation of System.Reflection.Emit.TypeBuilder.CreateType:Unter welchen Umständen ruft TypeBuilder.CreateType AppDomain.OnTypeResolveEvent auf?

Wenn das einschließende Typ ein Feld enthält, das ein Werttyp als ein verschachtelter Typ definiert ist (beispielsweise ein Feld, das eine Aufzählung als ein verschachtelter Typ definiert ist), der Create Methode aufrufen Auf dem umschließenden Typ wird ein AppDomain.TypeResolve-Ereignis generiert.

Ich versuche, einen Compiler zu debuggen, der dieses Ereignis unter einem ganz anderen (und völlig ohne Papiere!) Raising Umstand: Ich habe eine Schnittstelle (die keine Felder oder verschachtelte Typen enthalten kann) und eine der Methoden auf Die Schnittstelle hat einen generischen Parameter mit einer spezifischen Einschränkung. TypeResolve fragt nach dem Typ dieser Einschränkung.

Der Debugger sagt der Call-Stack wie folgt aussieht:

System.AppDomain.OnTypeResolveEvent 
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock 
System.Reflection.Emit.TypeBuilder.CreateType 
My.Compiler.TypeCreator.HandleTypeCreation 

aber weder der Debugger Dekompilierung TypeBuilder.CreateTypeNoLock noch the reference source zeigt, wo dieser Anruf stattfindet. Die Suche in der Referenzquelldatei nach "TypeResolve" ergibt überhaupt nichts, was bedeutet, dass etwas "Magie" vor sich geht.

Wo kann ich herausfinden, was die tatsächliche Logik hier ist, die dieses TypeResolve Ereignis auslöst, damit ich die Compiler-Implementierung beheben kann, um damit umzugehen?

+0

In solchen Fällen grep ich die CoreCRR oder SSCLI-Code für 'TypeResolve'. Ich bin überrascht, dass Ihre SSCLI-Suche nichts ergab. Meine corecrr Suche hat es getan. – usr

+0

Welche Art von Einschränkung verwenden Sie? Wurde der Typ, der dafür verwendet wird, bereits erstellt? Mir scheint, dass die Laufzeit dieses Ereignis auslösen muss, wenn Sie keine Typen in Abhängigkeitsreihenfolge erstellt haben. Der dekompilierte CreateTypeNoLock-Code zeigt, dass er CreateType für alle generischen Argumenttypen aufruft. – usr

Antwort

1

Werfen Sie einen Blick auf die AppDomain.TypeResolve Event in der Dokumentation. Unter bemerkt heißt es:

Das TypeResolve Ereignis tritt auf, wenn die Common Language Runtime ist nicht in der Lage die Versammlung zu bestimmen, die den angeforderten Typ erstellen können.

Auf der OnTypeResolveEvent Method in the Referencesource ist dieser Kommentar:

// Diese Methode wird von der VM genannt wird

Wenn Sie das Beispiel aus dem Eintrag Msdn verwenden und einen Haltepunkt setzen auf die OnTypeResolveEvent Methode erhalten Sie einen Stacktrace wie folgt:

mscorlib.dll!System.AppDomain.OnTypeResolveEvent(System.Reflection.RuntimeAssembly assembly, string typeName) 
[Native to Managed Transition] 
[Managed to Native Transition] 
mscorlib.dll!System.RuntimeTypeHandle.GetTypeByName(string name, bool throwOnError, bool ignoreCase, bool reflectionOnly, ref System.Threading.StackCrawlMark stackMark, System.IntPtr pPrivHostBinder, bool loadTypeFromPartialName) 
mscorlib.dll!System.RuntimeType.GetType(string typeName, bool throwOnError, bool ignoreCase, bool reflectionOnly, ref System.Threading.StackCrawlMark stackMark) 
mscorlib.dll!System.Type.GetType(string typeName, bool throwOnError) 
ResolveTest.exe!Test.Main() 

Also ich denke Es ist ziemlich klar, dass dieses Ereignis von der Laufzeit selbst und nicht von einer bestimmten Funktion in den Framework-Bibliotheken aufgerufen wird.

Um diese Situation zu behandeln, sollte es ausreichen, Ihren eigenen Delegaten auf das Ereignis AppDomain.TypeResolve zu setzen und die Laufzeit zu unterstützen, indem Sie den fehlenden Typ bereitstellen.

Verwandte Themen