次の方法で共有


TypeBuilder.CreateType メソッド

このクラスの Type オブジェクトを作成します。クラスのフィールドとメソッドを定義した後、 Type オブジェクトを読み込むために、 CreateType を呼び出します。

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

戻り値

このクラスの新しい Type オブジェクトを返します。

例外

例外の種類 条件
InvalidOperationException この型は既に作成されています。

または

外側の型が作成されていません。

または

この型は非抽象型ですが、抽象メソッドが含まれています。

または

この型は抽象型ですが、メソッド本体を持つメソッドがあります。

または

この型は抽象クラスまたはインターフェイスではありませんが、メソッド本体のないメソッドがあります。

NotSupportedException 型に無効な MSIL (Microsoft Intermediate Language) コードが含まれている場合。

または

分岐ターゲットが、1 バイト オフセットを使用して指定されているが、分岐からターゲットまでの距離が 127 バイトを超えています。

解説

この型が入れ子になった型の場合は、この型のメソッドを呼び出す前に、入れ子 (外側) の型で CreateType を呼び出す必要があります。

入れ子の型に、入れ子になった型と定義された値型のフィールド (たとえば入れ子になった型と定義された列挙型のフィールド) が含まれている場合は、入れ子の型に対して CreateType を呼び出すと TypeResolve イベントが生成されます。これは、入れ子になった型が完了するまで、ローダーが入れ子の型のサイズを確認できないからです。呼び出し元は、入れ子になった型の TypeBuilder に対して CreateType を呼び出すことで、 TypeResolve イベントのハンドラを定義し、入れ子になった型の定義を完了する必要があります。イベント ハンドラを定義する方法の例を次に示します。

 
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();
}

必要条件

プラットフォーム: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 ファミリ

参照

TypeBuilder クラス | TypeBuilder メンバ | System.Reflection.Emit 名前空間