TypeBuilder.CreateType Metoda

Definice

Vytvoří Type objekt pro třídu. Po definování polí a metod ve třídě se CreateType volá, aby se načetl jeho Type objekt.

public:
 Type ^ CreateType();
public Type? CreateType ();
public Type CreateType ();
member this.CreateType : unit -> Type
Public Function CreateType () As Type

Návraty

Vrátí nový Type objekt pro tuto třídu.

Výjimky

Ohraničující typ nebyl vytvořen.

-nebo-

Tento typ není abstraktní a obsahuje abstraktní metodu.

-nebo-

Tento typ není abstraktní třídou ani rozhraním a má metodu bez těla metody.

Chybný obsah popisku v ILGenerator: Definovali jste popisek bez volání MarkLabel(Label).

Typ obsahuje neplatný kód jazyka MSIL (Microsoft Intermediate Language).

-nebo-

Cíl větve je určen pomocí posunu 1 bajtu, ale cíl je ve vzdálenosti větší než 127 bajtů od větve.

Typ nelze načíst. Například obsahuje metodu static , která má konvenci HasThisvolání .

Příklady

Následující příklad kódu ukazuje, jak definovat obslužnou rutinu události pro AppDomain.TypeResolve událost, aby bylo možné volat metodu CreateType na vnořeném typu během CreateType volání na ohraničující typ.

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

Poznámky

Pokud je tento typ vnořeným typem, CreateType musí být metoda volána u ohraničujícího typu před zavoláním na vnořeném typu.

Pokud aktuální typ je odvozen z neúplného typu nebo implementuje neúplná rozhraní, zavolejte metodu CreateType nadřazeného typu a typy rozhraní před voláním na aktuální typ.

Pokud ohraničující typ obsahuje pole, které je hodnotovým typem definovaným jako vnořený typ (například pole, které je výčtem definovaným jako vnořený typ), volání CreateType metody u ohraničujícího typu vygeneruje AppDomain.TypeResolve událost. Důvodem je to, že zavaděč nemůže určit velikost ohraničujícího typu, dokud nebude vnořený typ dokončen. Volající by měl definovat obslužnou rutinu TypeResolve události, aby se dokončila definice vnořeného typu voláním CreateType objektu TypeBuilder , který představuje vnořený typ. Příklad kódu pro toto téma ukazuje, jak definovat takovou obslužnou rutinu události.

Typ se vytvoří pouze jednou, bez ohledu na to, kolikrát CreateType je metoda volána. Všechna volání vrací stejný Type objekt.

Platí pro