TypeBuilder.CreateType 方法

定義

建立這個類別的 Type 物件。 定義類別上的欄位和方法之後,呼叫 CreateType 以載入其 Type 物件。

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

傳回

傳回這個類別的新 Type 物件。

例外狀況

尚未建立封入類型。

-或-

這個類型為非抽象,而且包含抽象方法。

-或-

這個類型不是抽象類別或介面,而且包含沒有方法主體的方法。

ILGenerator 中有錯誤的標籤內容:您已定義標籤,但未呼叫 MarkLabel(Label)

這個類型包含無效的 Microsoft Intermediate Language (MSIL) 程式碼。

-或-

使用 1 個位元組位移指定分支目標,但目標與分支的距離大於 127 個位元組。

無法載入這個類型。 例如,其包含的 static 方法具有呼叫慣例 HasThis

範例

下列程式代碼範例示範如何定義 事件的事件處理程式AppDomain.TypeResolve,以便在封入型別的呼叫期間CreateType,在巢狀類型上呼叫 CreateType 方法。

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 ,藉由呼叫 CreateType 代表巢狀類型的 物件來完成 TypeBuilder 巢狀型別的定義。 本主題的程式代碼範例示範如何定義這類事件處理程式。

不論呼叫 方法的次數 CreateType 為何,類型只會建立一次。 所有呼叫都會傳回相同的 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