TypeBuilder.CreateType TypeBuilder.CreateType TypeBuilder.CreateType TypeBuilder.CreateType Method

定义

创建类的 Type 对象。Creates a Type object for the class. 定义了类的字段和方法后,调用 CreateType 以加载其 Type 对象。After defining fields and methods on the class, CreateType is called in order to load its Type object.

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

返回

为此类返回新的 Type 对象。Returns the new Type object for this class.

异常

尚未创建封闭类型。The enclosing type has not been created.

- 或 --or-

此类型是非抽象类型,且包含一个抽象方法。This type is non-abstract and contains an abstract method.

- 或 --or-

此类型不是抽象类或接口,并且具有一个没有方法体的方法。This type is not an abstract class or an interface and has a method without a method body.

此类型包含无效的 Microsoft 中间语言 (MSIL) 代码。The type contains invalid Microsoft intermediate language (MSIL) code.

- 或 --or-

分支目标使用 1 个字节的偏移量指定,但目标离分支的距离大于 127 个字节。The branch target is specified using a 1-byte offset, but the target is at a distance greater than 127 bytes from the branch.

无法加载此类型。The type cannot be loaded. 例如,它包含具有调用约定 HasThisstatic 方法。For example, it contains a static method that has the calling convention HasThis.

示例

下面的代码示例演示如何为AppDomain.TypeResolve事件定义事件处理程序,以便在CreateType调用封闭类型时在CreateType嵌套类型上调用方法。The following code example shows how to define an event handler for the AppDomain.TypeResolve event, in order to call the CreateType method on a nested type during a CreateType call on the enclosing type.

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 'NestedEnum


' 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 'TypeResolveHandler

注解

如果此类型是嵌套类型,则在CreateType对嵌套类型调用方法之前,必须在封闭类型上调用此方法。If this type is a nested type, the CreateType method must be called on the enclosing type before it is called on the nested type.

如果当前类型派生自不完整的类型或实现了不完整的接口CreateType ,请先在父类型和接口类型上调用方法,然后再在当前类型上调用该方法。If the current type derives from an incomplete type or implements incomplete interfaces, call the CreateType method on the parent type and the interface types before calling it on the current type.

如果封闭类型包含的字段是定义为嵌套类型的值类型(例如,作为定义为嵌套类型的枚举的字段),则对封闭类型调用CreateType方法将生成一个AppDomain.TypeResolve事件。If the enclosing type contains a field that is a value type defined as a nested type (for example, a field that is an enumeration defined as a nested type), calling the CreateType method on the enclosing type will generate a AppDomain.TypeResolve event. 这是因为加载程序不能确定封闭类型的大小,直到嵌套类型完成。This is because the loader cannot determine the size of the enclosing type until the nested type has been completed. 调用方应为TypeResolve事件定义处理程序,以通过在表示嵌套类型的TypeBuilder对象上调用CreateType来完成嵌套类型的定义。The caller should define a handler for the TypeResolve event to complete the definition of the nested type by calling CreateType on the TypeBuilder object that represents the nested type. 本主题的代码示例演示如何定义此类事件处理程序。The code example for this topic shows how to define such an event handler.

无论调用CreateType方法多少次,都只创建一次类型。A type is created only once, no matter how many times the CreateType method is called. 所有调用都返回相同Type的对象。All calls return the same Type object.

适用于