TypeBuilder.CreateType Método
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Crea un Type objeto para la clase . Después de definir campos y métodos en la clase , CreateType se llama a para cargar su Type objeto.
public:
Type ^ CreateType();
public Type CreateType();
member this.CreateType : unit -> Type
Public Function CreateType () As Type
Devoluciones
Devuelve el nuevo Type objeto de esta clase.
Excepciones
No se ha creado el tipo envolvente.
O bien
Este tipo no es abstracto y contiene un método abstracto.
O bien
Este tipo no es una clase abstracta o una interfaz y tiene un método sin un cuerpo del método.
Contenido de etiqueta incorrecto en ILGenerator: ha definido una etiqueta sin llamar a MarkLabel(Label).
El tipo contiene código de lenguaje intermedio (MSIL) no válido Microsoft.
O bien
El destino de rama se especifica mediante un desplazamiento de 1 byte, pero el destino es a una distancia mayor que 127 bytes de la rama.
No se puede cargar el tipo. Por ejemplo, contiene un static método que tiene la convención HasThisde llamada .
Ejemplos
En el ejemplo de código siguiente se muestra cómo definir un controlador de eventos para el AppDomain.TypeResolve evento, con el fin de llamar al CreateType método en un tipo anidado durante una CreateType llamada en el tipo envolvente.
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
Comentarios
Si este tipo es un tipo anidado, CreateType se debe llamar al método en el tipo envolvente antes de llamar al tipo anidado.
Si el tipo actual se deriva de un tipo incompleto o implementa interfaces incompletas, llame al CreateType método en el tipo primario y los tipos de interfaz antes de llamarlo en el tipo actual.
Si el tipo envolvente contiene un campo que es un tipo de valor definido como un tipo anidado (por ejemplo, un campo que es una enumeración definida como un tipo anidado), llamar al CreateType método en el tipo envolvente generará un AppDomain.TypeResolve evento. Esto se debe a que el cargador no puede determinar el tamaño del tipo envolvente hasta que se haya completado el tipo anidado. El autor de la llamada debe definir un controlador para que el TypeResolve evento complete la definición del tipo anidado llamando al CreateTypeTypeBuilder objeto que representa el tipo anidado. En el ejemplo de código de este tema se muestra cómo definir este controlador de eventos.
Un tipo solo se crea una vez, independientemente de cuántas veces se llame al CreateType método. Todas las llamadas devuelven el mismo Type objeto.