英語で読む

次の方法で共有


TypeBuilder.CreateType メソッド

定義

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

C#
public Type CreateType();
C#
public Type? CreateType();

戻り値

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

例外

囲む型が作成されていません。

- または -

この型は非抽象であり、抽象メソッドを含んでいます。

- または -

この型は抽象クラスまたはインターフェイスではなく、メソッド本体のないメソッドを持ちます。

ILGenerator 内の正しくないラベル コンテンツ: MarkLabel(Label) を呼び出さずにラベルが定義されています。

この型は正しくない MSIL (Microsoft Intermediate Language) コードを含んでいます。

- または -

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

型を読み込めません。 たとえば、呼び出し規則 HasThis を持つ static メソッドを含んでいます。

次のコード例は、外側の型の呼び出し中CreateTypeに入れ子になった型で メソッドをCreateType呼び出すために、 イベントのイベント ハンドラーAppDomain.TypeResolveを定義する方法を示しています。

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;

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

注釈

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

現在の型が不完全な型から派生している場合、または不完全なインターフェイスを実装している場合は、現在の型で呼び出 CreateType す前に、親型とインターフェイス型で メソッドを呼び出します。

外側の型に、入れ子になった型として定義された値型であるフィールド (入れ子になった型として定義された列挙体であるフィールドなど) が含まれている場合、外側の型で メソッドを呼び出すと CreateType イベントが生成 AppDomain.TypeResolve されます。 これは、入れ子になった型が完了するまで、ローダーが外側の型のサイズを判断できないためです。 呼び出し元は、入れ子になった型をTypeResolve表す オブジェクトで を呼び出CreateTypeTypeBuilderすことによって、入れ子になった型の定義を完了するイベントのハンドラーを定義する必要があります。 このトピックのコード例では、このようなイベント ハンドラーを定義する方法を示します。

メソッドが何回呼び出されても、 CreateType 型は 1 回だけ作成されます。 すべての呼び出しで同じ Type オブジェクトが返されます。

適用対象

製品 バージョン
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9, 10
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.1