ControlFlowBuilder Classe

Definição

Emite branches e blocos de exceção em um corpo do método.

public sealed class ControlFlowBuilder
Herança
ControlFlowBuilder

Exemplos

Este exemplo mostra como emitir um corpo do método com o manipulador de exceção usando ControlFlowBuilder:

// The following code emits method body similar to this C# code:

/* public static void ExceptionBlockTest(int x, int y)
   {
      try
      {
         Console.WriteLine(x / y);
      }
      catch (DivideByZeroException)
      {
         Console.WriteLine("Error: division by zero");
      }
   }
*/

public static InstructionEncoder ControlFlowBuilderDemo(MetadataBuilder metadata, 
    AssemblyReferenceHandle corlibAssemblyRef)
{
    var codeBuilder = new BlobBuilder();
    var flowBuilder = new ControlFlowBuilder();
    var encoder = new InstructionEncoder(codeBuilder, flowBuilder);

    // Get reference to System.Console
    AssemblyReferenceHandle systemConsoleAssemblyRef = metadata.AddAssemblyReference(
        name: metadata.GetOrAddString("System.Console"),
        version: new Version(4, 0, 0, 0),
        culture: default(StringHandle),
        publicKeyOrToken: default(BlobHandle),
        flags: default(AssemblyFlags),
        hashValue: default(BlobHandle));
    
    TypeReferenceHandle consoleTypeRefHandle = metadata.AddTypeReference(
        systemConsoleAssemblyRef,
        metadata.GetOrAddString("System"),
        metadata.GetOrAddString("Console"));

    // Get reference to void System.Console::WriteLine(int32)
    var methodSignature = new BlobBuilder();

    new BlobEncoder(methodSignature).
        MethodSignature(isInstanceMethod: false).
        Parameters(1, returnType => returnType.Void(), parameters => parameters.AddParameter().Type().Int32());

    BlobHandle sigBlobIndex1 = metadata.GetOrAddBlob(methodSignature);

    MemberReferenceHandle refWriteLineInt32 = metadata.AddMemberReference(
        consoleTypeRefHandle,
        metadata.GetOrAddString("WriteLine"),
        sigBlobIndex1);

    // Get reference to void System.Console::WriteLine(string)
    methodSignature = new BlobBuilder();

    new BlobEncoder(methodSignature).
        MethodSignature(isInstanceMethod: false).
        Parameters(1, returnType => returnType.Void(), parameters => parameters.AddParameter().Type().String());

    BlobHandle sigBlobIndex2 = metadata.GetOrAddBlob(methodSignature);

    MemberReferenceHandle refWriteLineString = metadata.AddMemberReference(
        consoleTypeRefHandle,
        metadata.GetOrAddString("WriteLine"),
        sigBlobIndex2);

    // Get reference to System.DivideByZeroException
    TypeReferenceHandle exceptionTypeRefHandle = metadata.AddTypeReference(
        corlibAssemblyRef,
        metadata.GetOrAddString("System"),
        metadata.GetOrAddString("DivideByZeroException"));
    
    LabelHandle labelTryStart = encoder.DefineLabel();
    LabelHandle labelTryEnd = encoder.DefineLabel();
    LabelHandle labelCatchStart = encoder.DefineLabel();
    LabelHandle labelCatchEnd = encoder.DefineLabel();
    LabelHandle labelExit = encoder.DefineLabel();

    flowBuilder.AddCatchRegion(labelTryStart, labelTryEnd, labelCatchStart, labelCatchEnd,
        exceptionTypeRefHandle);

    // .try {
    encoder.MarkLabel(labelTryStart);

    // ldarg.0
    encoder.OpCode(ILOpCode.Ldarg_0);

    // ldarg.1
    encoder.OpCode(ILOpCode.Ldarg_1);

    // div
    encoder.OpCode(ILOpCode.Div);

    // call void [System.Console]System.Console::WriteLine(int32)
    encoder.Call(refWriteLineInt32);

    // leave.s EXIT            
    encoder.Branch(ILOpCode.Leave_s, labelExit);
    encoder.MarkLabel(labelTryEnd);

    // } 
    // catch [System.Runtime]System.DivideByZeroException {
    encoder.MarkLabel(labelCatchStart);

    // pop
    encoder.OpCode(ILOpCode.Pop);
    
    // ldstr "Error: division by zero"
    encoder.LoadString(metadata.GetOrAddUserString("Error: division by zero"));

    // call void [System.Console]System.Console::WriteLine(string)
    encoder.Call(refWriteLineString);

    // leave.s EXIT            
    encoder.Branch(ILOpCode.Leave_s, labelExit);
    encoder.MarkLabel(labelCatchEnd);

    // } EXIT: ret
    encoder.MarkLabel(labelExit);
    encoder.OpCode(ILOpCode.Ret);
    
    return encoder;
}

Comentários

A ControlFlowBuilder classe é usada para criar branches e blocos de exceção em um corpo do método codificado por InstructionEncoder. Para obter mais informações sobre como emitir assemblies .NET, consulte a documentação da MetadataBuilder classe.

Construtores

ControlFlowBuilder()

Emite branches e blocos de exceção em um corpo do método.

Métodos

AddCatchRegion(LabelHandle, LabelHandle, LabelHandle, LabelHandle, EntityHandle)

Adiciona a região catch.

AddFaultRegion(LabelHandle, LabelHandle, LabelHandle, LabelHandle)

Adiciona a região fault.

AddFilterRegion(LabelHandle, LabelHandle, LabelHandle, LabelHandle, LabelHandle)

Adiciona a região catch.

AddFinallyRegion(LabelHandle, LabelHandle, LabelHandle, LabelHandle)

Adiciona a região finally.

Clear()

Limpa o estado interno do objeto, permitindo que a mesma instância seja reutilizado.

Equals(Object)

Determina se o objeto especificado é igual ao objeto atual.

(Herdado de Object)
GetHashCode()

Serve como a função de hash padrão.

(Herdado de Object)
GetType()

Obtém o Type da instância atual.

(Herdado de Object)
MemberwiseClone()

Cria uma cópia superficial do Object atual.

(Herdado de Object)
ToString()

Retorna uma cadeia de caracteres que representa o objeto atual.

(Herdado de Object)

Aplica-se a

Produto Versões
.NET Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8 (package-provided), 8, 9 (package-provided), 9
.NET Framework 4.7 (package-provided), 4.7.1 (package-provided), 4.7.2 (package-provided), 4.8 (package-provided)
.NET Standard 2.0 (package-provided)