Ler em inglês

Partilhar via


TypeBuilder.CreateType Método

Definição

Cria um objeto Type para a classe. Depois de definir campos e métodos na classe, CreateType é chamado para carregar seu objeto Type.

C#
public Type CreateType();
C#
public Type? CreateType();

Retornos

Retorna o novo objeto Type dessa classe.

Exceções

O tipo delimitador não foi criado.

- ou -

Esse tipo é não abstrato e contém um método abstrato.

- ou -

Esse tipo não é uma classe abstrata nem uma interface e tem um método sem um corpo do método.

Conteúdo de rótulo inadequado em ILGenerator: você definiu um rótulo sem chamar MarkLabel(Label).

O tipo contém código MSIL (Microsoft Intermediate Language) inválido.

- ou -

O destino da ramificação é especificado usando um deslocamento de 1 byte, mas está em uma distância maior que 127 bytes da ramificação.

O tipo não pode ser carregado. Por exemplo, contém um método static com a convenção de chamada HasThis.

Exemplos

O exemplo de código a seguir mostra como definir um manipulador de eventos para o AppDomain.TypeResolve evento, a fim de chamar o CreateType método em um tipo aninhado durante uma CreateType chamada no tipo delimitado.

C#
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;
    }
}

Comentários

Se esse tipo for um tipo aninhado, o CreateType método deverá ser chamado no tipo delimitado antes de ser chamado no tipo aninhado.

Se o tipo atual derivar de um tipo incompleto ou implementar interfaces incompletas, chame o CreateType método no tipo pai e os tipos de interface antes de chamá-lo no tipo atual.

Se o tipo delimitador contiver um campo que é um tipo de valor definido como um tipo aninhado (por exemplo, um campo que é uma enumeração definida como um tipo aninhado), chamar o CreateType método no tipo delimitador gerará um AppDomain.TypeResolve evento. Isso ocorre porque o carregador não pode determinar o tamanho do tipo delimitador até que o tipo aninhado tenha sido concluído. O chamador deve definir um manipulador para que o TypeResolve evento conclua a definição do tipo aninhado chamando CreateType no TypeBuilder objeto que representa o tipo aninhado. O exemplo de código para este tópico mostra como definir esse manipulador de eventos.

Um tipo é criado apenas uma vez, independentemente de quantas vezes o CreateType método é chamado. Todas as chamadas retornam o mesmo Type objeto.

Aplica-se a

Produto Versões
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9, 10
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.1