TypeBuilder.CreateType Metodo
Definizione
Importante
Alcune informazioni sono relative alla release non definitiva del prodotto, che potrebbe subire modifiche significative prima della release definitiva. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Crea un oggetto Type per la classe. Dopo aver definito i campi e metodi della classe CreateType
viene chiamato per caricare il relativo oggetto Type
.
public:
Type ^ CreateType();
public Type? CreateType ();
public Type CreateType ();
member this.CreateType : unit -> Type
Public Function CreateType () As Type
Restituisce
Restituisce il nuovo oggetto Type per questa classe.
Eccezioni
Il tipo di inclusione non è stato creato.
-oppure-
Questo tipo è non astratto e contiene un metodo astratto.
-oppure-
Questo tipo è una classe o un'interfaccia non astratta e ha un metodo senza corpo.
Contenuto dell'etichetta non valido in ILGenerator: È stata definita un'etichetta senza chiamare MarkLabel(Label).
Il tipo contiene codice MSIL (Microsoft Intermediate Language) non valido.
-oppure-
La destinazione branch viene specificata usando un offset di 1 byte, ma la destinazione si trova a una distanza maggiore di 127 byte dal branch.
Non è possibile caricare il tipo. Ad esempio, contiene un metodo static
con la convenzione di chiamata HasThis.
Esempio
Nell'esempio di codice seguente viene illustrato come definire un gestore eventi per l'evento AppDomain.TypeResolve , per chiamare il CreateType metodo su un tipo annidato durante una CreateType chiamata al tipo di inclusione.
using namespace System;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
using namespace System::Threading;
using namespace System::Text;
using namespace System::Resources;
using namespace System::Collections;
using namespace System::IO;
// Helper class called when a resolve type event is raised.
ref class TypeResolveHandler
{
private:
Module^ m_Module;
public:
TypeResolveHandler( Module^ mod )
{
m_Module = mod;
}
Assembly^ ResolveEvent( Object^ sender, ResolveEventArgs^ args );
};
ref class NestedEnum
{
internal:
static TypeBuilder^ enumType = nullptr;
static Type^ tNested = nullptr;
static Type^ tNesting = nullptr;
public:
static void Main()
{
AssemblyName^ asmName = gcnew AssemblyName;
asmName->Name = "NestedEnum";
AssemblyBuilder^ asmBuild = Thread::GetDomain()->DefineDynamicAssembly( asmName, AssemblyBuilderAccess::RunAndSave );
ModuleBuilder^ modBuild = asmBuild->DefineDynamicModule( "ModuleOne", "NestedEnum.dll" );
// Hook up the event listening.
TypeResolveHandler^ typeResolveHandler = gcnew TypeResolveHandler( modBuild );
// Add a listener for the type resolve events.
AppDomain^ currentDomain = Thread::GetDomain();
ResolveEventHandler^ resolveHandler = gcnew ResolveEventHandler( typeResolveHandler, &TypeResolveHandler::ResolveEvent );
currentDomain->TypeResolve += resolveHandler;
TypeBuilder^ tb = modBuild->DefineType( "AType", TypeAttributes::Public );
TypeBuilder^ eb = tb->DefineNestedType( "AnEnum", static_cast<TypeAttributes>(TypeAttributes::NestedPublic | TypeAttributes::Sealed), Enum::typeid, 0 );
eb->DefineField( "value__", int::typeid, static_cast<FieldAttributes>(FieldAttributes::Private | FieldAttributes::SpecialName) );
FieldBuilder^ fb = eb->DefineField( "Field1", eb, static_cast<FieldAttributes>(FieldAttributes::Public | FieldAttributes::Literal | FieldAttributes::Static) );
fb->SetConstant( 1 );
enumType = eb;
// Comment out this field.
// When this field is defined, the loader cannot determine the size
// of the type. Therefore, a TypeResolve event is generated when the
// nested type is completed.
tb->DefineField( "Field2", eb, FieldAttributes::Public );
tNesting = tb->CreateType();
if ( tNesting == nullptr )
Console::WriteLine( "NestingType CreateType failed but didn't throw!" );
try
{
tNested = eb->CreateType();
if ( tNested == nullptr )
Console::WriteLine( "NestedType CreateType failed but didn't throw!" );
}
catch ( Exception^ )
{
// This is needed because you might have already completed the type in the TypeResolve event.
}
if ( tNested != nullptr )
{
Type^ x = tNested->DeclaringType;
if ( x == nullptr )
Console::WriteLine( "Declaring type is null." );
else
Console::WriteLine( x->Name );
}
asmBuild->Save( "NestedEnum.dll" );
// Remove the listener for the type resolve events.
currentDomain->TypeResolve -= resolveHandler;
}
};
Assembly^ TypeResolveHandler::ResolveEvent( Object^ sender, ResolveEventArgs^ args )
{
Console::WriteLine( args->Name );
// Use args.Name to look up the type name. In this case, you are getting AnEnum.
try
{
NestedEnum::tNested = NestedEnum::enumType->CreateType();
}
catch ( Exception^ )
{
// This is needed to throw away InvalidOperationException.
// Loader might send the TypeResolve event more than once
// and the type might be complete already.
}
// Complete the type.
return m_Module->Assembly;
}
int main()
{
NestedEnum::Main();
}
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
using System.Text;
using System.Resources;
using System.Collections;
using System.IO;
internal class NestedEnum {
internal static TypeBuilder enumType = null;
internal static Type tNested = null;
internal static Type tNesting = null;
public static void Main(String[] args) {
AssemblyName asmName = new AssemblyName();
asmName.Name = "NestedEnum";
AssemblyBuilder asmBuild = Thread.GetDomain().DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder modBuild = asmBuild.DefineDynamicModule("ModuleOne", "NestedEnum.dll");
// Hook up the event listening.
TypeResolveHandler typeResolveHandler = new TypeResolveHandler(modBuild);
// Add a listener for the type resolve events.
AppDomain currentDomain = Thread.GetDomain();
ResolveEventHandler resolveHandler = new ResolveEventHandler(typeResolveHandler.ResolveEvent);
currentDomain.TypeResolve += resolveHandler;
TypeBuilder tb = modBuild.DefineType("AType", TypeAttributes.Public);
TypeBuilder eb = tb.DefineNestedType("AnEnum", TypeAttributes.NestedPublic | TypeAttributes.Sealed, typeof(Enum), null);
eb.DefineField("value__", typeof(int), FieldAttributes.Private | FieldAttributes.SpecialName);
FieldBuilder fb = eb.DefineField("Field1", eb, FieldAttributes.Public | FieldAttributes.Literal | FieldAttributes.Static);
fb.SetConstant(1);
enumType = eb;
// Comment out this field.
// When this field is defined, the loader cannot determine the size
// of the type. Therefore, a TypeResolve event is generated when the
// nested type is completed.
tb.DefineField("Field2", eb, FieldAttributes.Public);
tNesting = tb.CreateType();
if (tNesting == null)
Console.WriteLine("NestingType CreateType failed but didn't throw!");
try {
tNested = eb.CreateType();
if (tNested == null)
Console.WriteLine("NestedType CreateType failed but didn't throw!");
}
catch {
// This is needed because you might have already completed the type in the TypeResolve event.
}
if (tNested != null) {
Type x = tNested.DeclaringType;
if (x == null)
Console.WriteLine("Declaring type was null.");
else
Console.WriteLine(x.Name);
}
asmBuild.Save( "NestedEnum.dll" );
// Remove the listener for the type resolve events.
currentDomain.TypeResolve -= resolveHandler;
}
}
// Helper class called when a resolve type event is raised.
internal class TypeResolveHandler
{
private Module m_Module;
public TypeResolveHandler(Module mod)
{
m_Module = mod;
}
public Assembly ResolveEvent(Object sender, ResolveEventArgs args)
{
Console.WriteLine(args.Name);
// Use args.Name to look up the type name. In this case, you are getting AnEnum.
try {
NestedEnum.tNested = NestedEnum.enumType.CreateType();
}
catch {
// This is needed to throw away InvalidOperationException.
// Loader might send the TypeResolve event more than once
// and the type might be complete already.
}
// Complete the type.
return m_Module.Assembly;
}
}
Imports System.Reflection
Imports System.Reflection.Emit
Imports System.Threading
Imports System.Text
Imports System.Resources
Imports System.Collections
Imports System.IO
Friend Class NestedEnum
Friend Shared enumType As TypeBuilder = Nothing
Friend Shared tNested As Type = Nothing
Friend Shared tNesting As Type = Nothing
Public Shared Sub Main()
Dim asmName As New AssemblyName()
asmName.Name = "NestedEnum"
Dim asmBuild As AssemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave)
Dim modBuild As ModuleBuilder = asmBuild.DefineDynamicModule("ModuleOne", "NestedEnum.dll")
' Hook up the event listening.
Dim typeResolveHandler As New TypeResolveHandler(modBuild)
' Add a listener for the type resolve events.
Dim currentDomain As AppDomain = Thread.GetDomain()
Dim resolveHandler As ResolveEventHandler = AddressOf typeResolveHandler.ResolveEvent
AddHandler currentDomain.TypeResolve, resolveHandler
Dim tb As TypeBuilder = modBuild.DefineType("AType", TypeAttributes.Public)
Dim eb As TypeBuilder = tb.DefineNestedType("AnEnum", TypeAttributes.NestedPublic Or TypeAttributes.Sealed, GetType([Enum]))
eb.DefineField("value__", GetType(Integer), FieldAttributes.Private Or FieldAttributes.SpecialName)
Dim fb As FieldBuilder = eb.DefineField("Field1", eb, FieldAttributes.Public Or FieldAttributes.Literal Or FieldAttributes.Static)
fb.SetConstant(1)
enumType = eb
' Comment out this field.
' When this field is defined, the loader cannot determine the size
' of the type. Therefore, a TypeResolve event is generated when the
' nested type is completed.
tb.DefineField("Field2", eb, FieldAttributes.Public)
tNesting = tb.CreateType()
If tNesting Is Nothing Then
Console.WriteLine("NestingType CreateType failed but didn't throw!")
End If
Try
tNested = eb.CreateType()
If tNested Is Nothing Then
Console.WriteLine("NestedType CreateType failed but didn't throw!")
End If
Catch
End Try ' This is needed because you might have already completed the type in the TypeResolve event.
If Not (tNested Is Nothing) Then
Dim x As Type = tNested.DeclaringType
If x Is Nothing Then
Console.WriteLine("Declaring type is Nothing.")
Else
Console.WriteLine(x.Name)
End If
End If
asmBuild.Save("NestedEnum.dll")
' Remove the listener for the type resolve events.
RemoveHandler currentDomain.TypeResolve, resolveHandler
End Sub
End Class
' Helper class called when a resolve type event is raised.
Friend Class TypeResolveHandler
Private m_Module As [Module]
Public Sub New([mod] As [Module])
m_Module = [mod]
End Sub
Public Function ResolveEvent(sender As [Object], args As ResolveEventArgs) As [Assembly]
Console.WriteLine(args.Name)
' Use args.Name to look up the type name. In this case, you are getting AnEnum.
Try
NestedEnum.tNested = NestedEnum.enumType.CreateType()
Catch
End Try ' This is needed to throw away InvalidOperationException.
' Loader might send the TypeResolve event more than once
' and the type might be complete already.
' Complete the type.
Return m_Module.Assembly
End Function 'ResolveEvent
End Class
Commenti
Se questo tipo è un tipo annidato, è necessario chiamare il CreateType metodo sul tipo di inclusione prima che venga chiamato sul tipo annidato.
Se il tipo corrente deriva da un tipo incompleto o implementa interfacce incomplete, chiamare il CreateType metodo sul tipo padre e sui tipi di interfaccia prima di chiamarlo sul tipo corrente.
Se il tipo di inclusione contiene un campo che è un tipo valore definito come tipo annidato , ad esempio un campo che è un'enumerazione definita come tipo annidato, la chiamata al CreateType metodo sul tipo di inclusione genererà un AppDomain.TypeResolve evento. Questo perché il caricatore non è in grado di determinare le dimensioni del tipo di inclusione fino al completamento del tipo annidato. Il chiamante deve definire un gestore per l'evento TypeResolve per completare la definizione del tipo annidato chiamando CreateType sull'oggetto TypeBuilder che rappresenta il tipo annidato. Nell'esempio di codice di questo argomento viene illustrato come definire un gestore eventi di questo tipo.
Un tipo viene creato una sola volta, indipendentemente dal numero di chiamate del CreateType metodo. Tutte le chiamate restituiscono lo stesso Type oggetto.