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 上的文件。

API MetadataBuilder 操作低级别的元数据构造,例如表或 blob。 有关使用 C# 动态生成程序集的更简单方法,请参阅 CSharpCompilation Roslyn API。

CLI 元数据的格式由 ECMA-335 规范定义。 有关详细信息,请参阅 Ecma 国际网站上的标准 ECMA-335 - 公共语言基础结构 (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)

适用于