다음을 통해 공유


TypeBuilder.CreateType 메서드

정의

해당 클래스에 대한 Type 개체를 만듭니다. 클래스의 필드 및 메서드를 정의한 후에 CreateType을 호출하여 해당 클래스의 Type 개체를 로드합니다.

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

반환

이 클래스에 대한 새 Type 개체를 반환합니다.

예외

바깥쪽 형식이 만들어지지 않았습니다.

또는

이 형식이 비추상 형식이고 추상 메서드가 포함된 경우

또는

이 형식이 추상 클래스 또는 인터페이스가 아니고 메서드 본문이 없는 메서드가 들어 있는 경우

ILGenerator의 잘못된 레이블 내용: MarkLabel(Label)을 호출하지 않고 레이블을 정의했습니다.

형식에 잘못된 MSIL(Microsoft Intermediate Language) 코드가 들어 있는 경우

또는

분기 대상을 1바이트 오프셋으로 지정했지만 분기 대상이 분기에서 128바이트 이상 떨어져 있는 경우

형식을 로드할 수 없는 경우. 예를 들어 호출 규칙 HasThis가 있는 static 메서드가 포함되어 있습니다.

예제

다음 코드 예제에서는 호출 하는 동안 중첩된 형식에서 메서드를 호출 CreateType 하기 위해 이벤트에 대 AppDomain.TypeResolveCreateType 이벤트 처리기를 정의 하는 방법을 보여 주는 바 묶는 형식입니다.

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

설명

이 형식이 중첩된 형식인 CreateType 경우 중첩된 형식에서 호출되기 전에 바깥쪽 형식에서 메서드를 호출해야 합니다.

현재 형식이 불완전한 형식에서 파생되거나 불완전한 인터페이스를 구현하는 경우 현재 형식에서 호출하기 전에 부모 형식 및 인터페이스 형식에서 메서드를 호출 CreateType 합니다.

바깥쪽 형식에 중첩 형식으로 정의된 값 형식인 필드(예: 중첩된 형식으로 정의된 필드)가 포함된 경우 바깥쪽 형식에서 메서드를 호출 CreateType 하면 이벤트가 생성 AppDomain.TypeResolve 됩니다. 중첩된 형식이 완료될 때까지 로더가 바깥쪽 형식의 크기를 확인할 수 없기 때문입니다. 호출자는 중첩된 형식을 나타내는 개체를 호출 CreateType 하여 중첩 형식의 정의를 완료하기 위해 이벤트에 대한 TypeResolveTypeBuilder 처리기를 정의해야 합니다. 이 항목의 코드 예제에서는 이러한 이벤트 처리기를 정의하는 방법을 보여줍니다.

메서드가 호출된 횟수 CreateType 에 관계없이 형식은 한 번만 만들어집니다. 모든 호출은 동일한 Type 개체를 반환합니다.

적용 대상