This documentation is archived and is not being maintained.

TypeBuilder.CreateType Method

Creates a Type object for the class. After defining fields and methods on the class, CreateType is called in order to load its Type object.

[Visual Basic]
Public Function CreateType() As Type
[C#]
public Type CreateType();
[C++]
public: Type* CreateType();
[JScript]
public function CreateType() : Type;

Return Value

Returns the new Type object for this class.

Exceptions

Exception Type Condition
InvalidOperationException This type has been previously created.

-or-

The enclosing type has not been created.

-or-

This type is non-abstract and contains an abstract method.

-or-

This type is abstract and has a method with a method body.

-or-

This type is not an abstract class or an interface and has a method without a method body.

NotSupportedException If the type contains invalid Microsoft Intermediate Language (MSIL) code.

-or-

The branch target is specified using a 1-byte offset but the target is at a distance greater than 127 bytes from the branch.

Remarks

If this type is a nested type, the CreateType must be called on the nesting (enclosing) type before calling the method on this type.

If the nesting type contains a field that is a value type defined as a nested type (for example, a field that is an enum defined as a nested type), calling CreateType on the nesting type will generate a TypeResolve event. This is because the loader cannot determine the size of the nesting type until the nested type has been completed. The caller should define a handler for the TypeResolve event to complete the definition of the nested type by calling CreateType on the nested type's TypeBuilder. The following example shows how to define the event handler.

[Visual Basic] 
Imports System
Imports System.Reflection
Imports System.Reflection.Emit
Imports System.Threading
Imports System.Text
Imports System.Resources
Imports System.Collections
Imports System.IO

Public 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 'Main
End Class 'NestedEnum


' Helper class called when a resolve type event is raised.
Class TypeResolveHandler
   Private m_Module As [Module]
   
   
   Public Sub New([mod] As [Module])
      m_Module = [mod]
   End Sub 'New
   
   
   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 'TypeResolveHandler


[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;

public 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.
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;
    }
}
    

[C++] 
#using <mscorlib.dll>

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.
__gc class TypeResolveHandler {
private:
   Module*  m_Module;

public:
   TypeResolveHandler(Module* mod) {
      m_Module = mod;
   }

   Assembly* ResolveEvent(Object* sender, ResolveEventArgs* args);
};

public __gc class NestedEnum {
public private:
   static TypeBuilder* enumType = 0;
   static Type* tNested = 0;
   static Type* tNesting = 0;

public:
   static void Main() {
      AssemblyName* asmName = new AssemblyName();
      asmName->Name = S"NestedEnum";
      AssemblyBuilder*  asmBuild = Thread::GetDomain()->DefineDynamicAssembly(
         asmName,
         AssemblyBuilderAccess::RunAndSave);
      ModuleBuilder*  modBuild = asmBuild->DefineDynamicModule(S"ModuleOne", S"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,
         &TypeResolveHandler::ResolveEvent);
      currentDomain->TypeResolve += resolveHandler;

      TypeBuilder*  tb = modBuild->DefineType(S"AType", TypeAttributes::Public);
      TypeBuilder*  eb = tb->DefineNestedType(
         S"AnEnum",
         static_cast<TypeAttributes>(TypeAttributes::NestedPublic | TypeAttributes::Sealed),
         __typeof(Enum), 0);
      eb->DefineField(S"value__", __typeof(int),
         static_cast<FieldAttributes>(FieldAttributes::Private | FieldAttributes::SpecialName));
      FieldBuilder*  fb = eb->DefineField(S"Field1", eb,
         static_cast<FieldAttributes>(FieldAttributes::Public | FieldAttributes::Literal | FieldAttributes::Static));
      fb->SetConstant(__box(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(S"Field2", eb, FieldAttributes::Public);

      tNesting = tb->CreateType();
      if (tNesting == 0)
         Console::WriteLine(S"NestingType CreateType failed but didn't throw!");

      try {
         tNested = eb->CreateType();
         if (tNested == 0)
            Console::WriteLine(S"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 != 0) {
         Type*  x = tNested->DeclaringType;
         if (x == 0)
            Console::WriteLine(S"Declaring type is null.");
         else
            Console::WriteLine(x->Name);
      }

      asmBuild->Save(S"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();
}

Requirements

Platforms: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 family

See Also

TypeBuilder Class | TypeBuilder Members | System.Reflection.Emit Namespace

Show: