MetadataBuilder 類別

定義

MetadataBuilder 類別會以高效能的方式寫入元件的中繼資料。 其設計目的是要供編譯器和其他組件產生工具使用。

public ref class MetadataBuilder sealed
public sealed class MetadataBuilder
type MetadataBuilder = class
Public NotInheritable Class MetadataBuilder
繼承
MetadataBuilder

範例

此範例示範如何使用 發出主控台應用程式元件 MetadataBuilder

private static readonly Guid s_guid = new Guid("87D4DBE1-1143-4FAD-AAB3-1001F92068E6");
private static readonly BlobContentId s_contentId = new BlobContentId(s_guid, 0x04030201);

private static MethodDefinitionHandle EmitHelloWorld(MetadataBuilder metadata, BlobBuilder ilBuilder)
{
    // Create module and assembly for a console application.
    metadata.AddModule(
        0,
        metadata.GetOrAddString("ConsoleApplication.exe"),
        metadata.GetOrAddGuid(s_guid),
        default(GuidHandle),
        default(GuidHandle));

    metadata.AddAssembly(
        metadata.GetOrAddString("ConsoleApplication"),
        version: new Version(1, 0, 0, 0),
        culture: default(StringHandle),
        publicKey: default(BlobHandle),
        flags: 0,
        hashAlgorithm: AssemblyHashAlgorithm.None);

    // Create references to System.Object and System.Console types.
    AssemblyReferenceHandle mscorlibAssemblyRef = metadata.AddAssemblyReference(
        name: metadata.GetOrAddString("mscorlib"),
        version: new Version(4, 0, 0, 0),
        culture: default(StringHandle),
        publicKeyOrToken: metadata.GetOrAddBlob(
            new byte[] { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 }
            ),
        flags: default(AssemblyFlags),
        hashValue: default(BlobHandle));

    TypeReferenceHandle systemObjectTypeRef = metadata.AddTypeReference(
        mscorlibAssemblyRef,
        metadata.GetOrAddString("System"),
        metadata.GetOrAddString("Object"));

    TypeReferenceHandle systemConsoleTypeRefHandle = metadata.AddTypeReference(
        mscorlibAssemblyRef,
        metadata.GetOrAddString("System"),
        metadata.GetOrAddString("Console"));

    // Get reference to Console.WriteLine(string) method.
    var consoleWriteLineSignature = new BlobBuilder();

    new BlobEncoder(consoleWriteLineSignature).
        MethodSignature().
        Parameters(1,
            returnType => returnType.Void(),
            parameters => parameters.AddParameter().Type().String());

    MemberReferenceHandle consoleWriteLineMemberRef = metadata.AddMemberReference(
        systemConsoleTypeRefHandle,
        metadata.GetOrAddString("WriteLine"),
        metadata.GetOrAddBlob(consoleWriteLineSignature));

    // Get reference to Object's constructor.
    var parameterlessCtorSignature = new BlobBuilder();

    new BlobEncoder(parameterlessCtorSignature).
        MethodSignature(isInstanceMethod: true).
        Parameters(0, returnType => returnType.Void(), parameters => { });

    BlobHandle parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature);

    MemberReferenceHandle objectCtorMemberRef = metadata.AddMemberReference(
        systemObjectTypeRef,
        metadata.GetOrAddString(".ctor"),
        parameterlessCtorBlobIndex);

    // Create signature for "void Main()" method.
    var mainSignature = new BlobBuilder();

    new BlobEncoder(mainSignature).
        MethodSignature().
        Parameters(0, returnType => returnType.Void(), parameters => { });

    var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder);

    var codeBuilder = new BlobBuilder();
    InstructionEncoder il;
    
    // Emit IL for Program::.ctor
    il = new InstructionEncoder(codeBuilder);

    // ldarg.0
    il.LoadArgument(0); 

    // call instance void [mscorlib]System.Object::.ctor()
    il.Call(objectCtorMemberRef);

    // ret
    il.OpCode(ILOpCode.Ret);

    int ctorBodyOffset = methodBodyStream.AddMethodBody(il);
    codeBuilder.Clear();

    // Emit IL for Program::Main
    var flowBuilder = new ControlFlowBuilder();
    il = new InstructionEncoder(codeBuilder, flowBuilder);

    // ldstr "hello"
    il.LoadString(metadata.GetOrAddUserString("Hello, world"));

    // call void [mscorlib]System.Console::WriteLine(string)
    il.Call(consoleWriteLineMemberRef);

    // ret
    il.OpCode(ILOpCode.Ret);

    int mainBodyOffset = methodBodyStream.AddMethodBody(il);
    codeBuilder.Clear();

    // Create method definition for Program::Main
    MethodDefinitionHandle mainMethodDef = metadata.AddMethodDefinition(
        MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
        MethodImplAttributes.IL,
        metadata.GetOrAddString("Main"),
        metadata.GetOrAddBlob(mainSignature),
        mainBodyOffset,
        parameterList: default(ParameterHandle));

    // Create method definition for Program::.ctor
    MethodDefinitionHandle ctorDef = metadata.AddMethodDefinition(
        MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
        MethodImplAttributes.IL,
        metadata.GetOrAddString(".ctor"),
        parameterlessCtorBlobIndex,
        ctorBodyOffset,
        parameterList: default(ParameterHandle));

    // Create type definition for the special <Module> type that holds global functions
    metadata.AddTypeDefinition(
        default(TypeAttributes),
        default(StringHandle),
        metadata.GetOrAddString("<Module>"),
        baseType: default(EntityHandle),
        fieldList: MetadataTokens.FieldDefinitionHandle(1),
        methodList: mainMethodDef);

    // Create type definition for ConsoleApplication.Program
    metadata.AddTypeDefinition(
        TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit,
        metadata.GetOrAddString("ConsoleApplication"),
        metadata.GetOrAddString("Program"),
        baseType: systemObjectTypeRef,
        fieldList: MetadataTokens.FieldDefinitionHandle(1),
        methodList: mainMethodDef);
    
    return mainMethodDef;
}

private static void WritePEImage(
    Stream peStream,
    MetadataBuilder metadataBuilder,
    BlobBuilder ilBuilder,
    MethodDefinitionHandle entryPointHandle
    )
{
    // Create executable with the managed metadata from the specified MetadataBuilder.
    var peHeaderBuilder = new PEHeaderBuilder(
        imageCharacteristics: Characteristics.ExecutableImage
        );

    var peBuilder = new ManagedPEBuilder(
        peHeaderBuilder,
        new MetadataRootBuilder(metadataBuilder),
        ilBuilder,
        entryPoint: entryPointHandle,
        flags: CorFlags.ILOnly,
        deterministicIdProvider: content => s_contentId);

    // Write executable into the specified stream.
    var peBlob = new BlobBuilder();
    BlobContentId contentId = peBuilder.Serialize(peBlob);
    peBlob.WriteContentTo(peStream);
}

public static void BuildHelloWorldApp()
{
    using var peStream = new FileStream(
        "ConsoleApplication.exe", FileMode.OpenOrCreate, FileAccess.ReadWrite
        );
    
    var ilBuilder = new BlobBuilder();
    var metadataBuilder = new MetadataBuilder();

    MethodDefinitionHandle entryPoint = EmitHelloWorld(metadataBuilder, ilBuilder);
    WritePEImage(peStream, metadataBuilder, ilBuilder, entryPoint);
}

備註

類別 MetadataBuilder 可讓您以程式設計方式產生元件。 這些元件可以儲存到檔案,不同于 類別所產生的 AssemblyBuilder 動態元件,這不支援將元件儲存至 .NET 5+ 和 .NET Core 上的檔案。

MetadataBuilderAPI 會操作低階中繼資料建構,例如資料表或 Blob。 如需使用 C# 動態產生元件的簡單方式,請參閱 CSharpCompilation Roslyn API 中的 。

CLI 中繼資料的格式是由 ECMA-335 規格所定義。 如需詳細資訊,請參閱 Ecma International 網站上的 標準 ECMA-335 - Common Language Infrastructure (CLI)

建構函式

MetadataBuilder(Int32, Int32, Int32, Int32)

建立用於中繼資料表和堆積的產生器。

方法

AddAssembly(StringHandle, Version, StringHandle, BlobHandle, AssemblyFlags, AssemblyHashAlgorithm)

MetadataBuilder 類別會以高效能的方式寫入元件的中繼資料。 其設計目的是要供編譯器和其他組件產生工具使用。

AddAssemblyFile(StringHandle, BlobHandle, Boolean)

MetadataBuilder 類別會以高效能的方式寫入元件的中繼資料。 其設計目的是要供編譯器和其他組件產生工具使用。

AddAssemblyReference(StringHandle, Version, StringHandle, BlobHandle, AssemblyFlags, BlobHandle)

MetadataBuilder 類別會以高效能的方式寫入元件的中繼資料。 其設計目的是要供編譯器和其他組件產生工具使用。

AddConstant(EntityHandle, Object)

新增參數、欄位或屬性的預設值。

AddCustomAttribute(EntityHandle, EntityHandle, BlobHandle)

新增自訂屬性。

AddCustomDebugInformation(EntityHandle, GuidHandle, BlobHandle)

新增自訂偵錯資訊。

AddDeclarativeSecurityAttribute(EntityHandle, DeclarativeSecurityAction, BlobHandle)

將宣告式安全性屬性新增至類型、方法或組件。

AddDocument(BlobHandle, GuidHandle, BlobHandle, GuidHandle)

新增文件偵錯資訊。

AddEncLogEntry(EntityHandle, EditAndContinueOperation)

MetadataBuilder 類別會以高效能的方式寫入元件的中繼資料。 其設計目的是要供編譯器和其他組件產生工具使用。

AddEncMapEntry(EntityHandle)

MetadataBuilder 類別會以高效能的方式寫入元件的中繼資料。 其設計目的是要供編譯器和其他組件產生工具使用。

AddEvent(EventAttributes, StringHandle, EntityHandle)

新增事件定義。

AddEventMap(TypeDefinitionHandle, EventDefinitionHandle)

MetadataBuilder 類別會以高效能的方式寫入元件的中繼資料。 其設計目的是要供編譯器和其他組件產生工具使用。

AddExportedType(TypeAttributes, StringHandle, StringHandle, EntityHandle, Int32)

新增匯出類型。

AddFieldDefinition(FieldAttributes, StringHandle, BlobHandle)

新增欄位定義。

AddFieldLayout(FieldDefinitionHandle, Int32)

定義欄位定義的欄位配置。

AddFieldRelativeVirtualAddress(FieldDefinitionHandle, Int32)

新增對應 (從欄位到其儲存在 PE 映像中的初始值)。

AddGenericParameter(EntityHandle, GenericParameterAttributes, StringHandle, Int32)

新增泛型參數定義。

AddGenericParameterConstraint(GenericParameterHandle, EntityHandle)

將類型條件約束新增至泛型參數。

AddImportScope(ImportScopeHandle, BlobHandle)

新增本機範圍偵錯資訊。

AddInterfaceImplementation(TypeDefinitionHandle, EntityHandle)

將介面實作新增至類型。

AddLocalConstant(StringHandle, BlobHandle)

新增本機常數偵錯資訊。

AddLocalScope(MethodDefinitionHandle, ImportScopeHandle, LocalVariableHandle, LocalConstantHandle, Int32, Int32)

新增本機範圍偵錯資訊。

AddLocalVariable(LocalVariableAttributes, Int32, StringHandle)

新增本機變數偵錯資訊。

AddManifestResource(ManifestResourceAttributes, StringHandle, EntityHandle, UInt32)

新增資訊清單資源。

AddMarshallingDescriptor(EntityHandle, BlobHandle)

將封送處理資訊新增至欄位或參數。

AddMemberReference(EntityHandle, StringHandle, BlobHandle)

新增 MemberRef 資料表資料列。

AddMethodDebugInformation(DocumentHandle, BlobHandle)

新增方法偵錯資訊。

AddMethodDefinition(MethodAttributes, MethodImplAttributes, StringHandle, BlobHandle, Int32, ParameterHandle)

新增方法定義。

AddMethodImplementation(TypeDefinitionHandle, EntityHandle, EntityHandle)

定義類型中方法宣告的實作。

AddMethodImport(MethodDefinitionHandle, MethodImportAttributes, StringHandle, ModuleReferenceHandle)

將匯入資訊新增至方法定義。

AddMethodSemantics(EntityHandle, MethodSemanticsAttributes, MethodDefinitionHandle)

將方法 (getter、setter、adder 等) 與屬性或事件建立關聯。

AddMethodSpecification(EntityHandle, BlobHandle)

新增方法規格 (具現化)。

AddModule(Int32, StringHandle, GuidHandle, GuidHandle, GuidHandle)

MetadataBuilder 類別會以高效能的方式寫入元件的中繼資料。 其設計目的是要供編譯器和其他組件產生工具使用。

AddModuleReference(StringHandle)

MetadataBuilder 類別會以高效能的方式寫入元件的中繼資料。 其設計目的是要供編譯器和其他組件產生工具使用。

AddNestedType(TypeDefinitionHandle, TypeDefinitionHandle)

定義指定類型定義的巢狀關聯性。

AddParameter(ParameterAttributes, StringHandle, Int32)

新增參數定義。

AddProperty(PropertyAttributes, StringHandle, BlobHandle)

新增屬性定義。

AddPropertyMap(TypeDefinitionHandle, PropertyDefinitionHandle)

MetadataBuilder 類別會以高效能的方式寫入元件的中繼資料。 其設計目的是要供編譯器和其他組件產生工具使用。

AddStandaloneSignature(BlobHandle)

MetadataBuilder 類別會以高效能的方式寫入元件的中繼資料。 其設計目的是要供編譯器和其他組件產生工具使用。

AddStateMachineMethod(MethodDefinitionHandle, MethodDefinitionHandle)

新增狀態機器方法偵錯資訊。

AddTypeDefinition(TypeAttributes, StringHandle, StringHandle, EntityHandle, FieldDefinitionHandle, MethodDefinitionHandle)

新增類型定義。

AddTypeLayout(TypeDefinitionHandle, UInt16, UInt32)

定義類型定義的類型配置。

AddTypeReference(EntityHandle, StringHandle, StringHandle)

新增類型參考。

AddTypeSpecification(BlobHandle)

MetadataBuilder 類別會以高效能的方式寫入元件的中繼資料。 其設計目的是要供編譯器和其他組件產生工具使用。

Equals(Object)

判斷指定的物件是否等於目前的物件。

(繼承來源 Object)
GetHashCode()

做為預設雜湊函式。

(繼承來源 Object)
GetOrAddBlob(BlobBuilder)

將指定的 Blob 從不可變位元組陣列新增至 Blob 堆積 (如果尚未存在)。

GetOrAddBlob(Byte[])

將指定的 Blob 新增至 Blob 堆積 (如果尚未存在)。

GetOrAddBlob(ImmutableArray<Byte>)

將指定的 Blob 從位元組陣列新增至 Blob 堆積 (如果尚未存在)。

GetOrAddBlobUTF16(String)

使用 UTF16 編碼將字串編碼為 Blob,並將其新增至 Blob 堆積 (如果尚未存在)。

GetOrAddBlobUTF8(String, Boolean)

使用 UTF8 編碼將字串編碼為 Blob,並將其新增至 Blob 堆積 (如果尚未存在)。

GetOrAddConstantBlob(Object)

將常數值編碼為 Blob,並將其新增至 Blob 堆積 (如果尚未存在)。 請使用 UTF16 來編碼字串常數。

GetOrAddDocumentName(String)

將偵錯文件名稱編碼,並將其新增至 Blob 堆積 (如果尚未存在)。

GetOrAddGuid(Guid)

將指定的 GUID 新增至 GUID 堆積 (如果尚未存在)。

GetOrAddString(String)

將指定的字串新增至字串堆積 (如果尚未存在)。

GetOrAddUserString(String)

將指定的字串新增至使用者字串堆積 (如果尚未存在)。

GetRowCount(TableIndex)

傳回所指定資料表中目前的項目數。

GetRowCounts()

傳回每個資料表中目前的項目數。

GetType()

取得目前執行個體的 Type

(繼承來源 Object)
MemberwiseClone()

建立目前 Object 的淺層複製。

(繼承來源 Object)
ReserveGuid()

在 GUID 堆積上為 GUID 保留空間。

ReserveUserString(Int32)

在使用者字串堆積上為指定長度的字串保留空間。

SetCapacity(HeapIndex, Int32)

設定指定堆積的容量。

SetCapacity(TableIndex, Int32)

設定指定資料表的容量。

ToString()

傳回代表目前物件的字串。

(繼承來源 Object)

適用於