ILGenerator.DefineLabel Método

Definição

Declara um novo rótulo.

public virtual System.Reflection.Emit.Label DefineLabel ();
public abstract System.Reflection.Emit.Label DefineLabel ();

Retornos

Um novo rótulo que pode ser usado como um token para ramificação.

Exemplos

O exemplo de código abaixo demonstra o uso contextual do DefineLabel método .


using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;

class ILLabelDemo {

   public static Type BuildAdderType() {

    AppDomain myDomain = Thread.GetDomain();
    AssemblyName myAsmName = new AssemblyName();
    myAsmName.Name = "AdderExceptionAsm";
    AssemblyBuilder myAsmBldr = myDomain.DefineDynamicAssembly(myAsmName,
                                 AssemblyBuilderAccess.Run);

    ModuleBuilder myModBldr = myAsmBldr.DefineDynamicModule("AdderExceptionMod");

    TypeBuilder myTypeBldr = myModBldr.DefineType("Adder");

    Type[] adderParams = new Type[] {typeof(int), typeof(int)};

    // This method will add two numbers which are 100 or less. If either of the
    // passed integer vales are greater than 100, it will return the value of -1.

    MethodBuilder adderBldr = myTypeBldr.DefineMethod("DoAdd",
                            MethodAttributes.Public |
                            MethodAttributes.Static,
                            typeof(int),
                            adderParams);
    ILGenerator adderIL = adderBldr.GetILGenerator();

    // In order to successfully branch, we need to create labels
    // representing the offset IL instruction block to branch to.
    // These labels, when the MarkLabel(Label) method is invoked,
    // will specify the IL instruction to branch to.
                                                                
    Label failed = adderIL.DefineLabel();
    Label endOfMthd = adderIL.DefineLabel();

    // First, load argument 0 and the integer value of "100" onto the
    // stack. If arg0 > 100, branch to the label "failed", which is marked
    // as the address of the block that loads -1 onto the stack, bypassing
    // the addition.

    adderIL.Emit(OpCodes.Ldarg_0);
    adderIL.Emit(OpCodes.Ldc_I4_S, 100);
    adderIL.Emit(OpCodes.Bgt_S, failed);

    // Now, check to see if argument 1 was greater than 100. If it was,
    // branch to "failed." Otherwise, fall through and perform the addition,
    // branching unconditionally to the instruction at the label "endOfMthd".

    adderIL.Emit(OpCodes.Ldarg_1);
    adderIL.Emit(OpCodes.Ldc_I4_S, 100);
    adderIL.Emit(OpCodes.Bgt_S, failed);

    adderIL.Emit(OpCodes.Ldarg_0);
    adderIL.Emit(OpCodes.Ldarg_1);
    adderIL.Emit(OpCodes.Add_Ovf_Un);
    adderIL.Emit(OpCodes.Br_S, endOfMthd);

    // If this label is branched to (the failure case), load -1 onto the stack
    // and fall through to the return opcode.
    adderIL.MarkLabel(failed);
    adderIL.Emit(OpCodes.Ldc_I4_M1);

    // The end of the method. If both values were less than 100, the
    // correct result will return. If one of the arguments was greater
    // than 100, the result will be -1.

    adderIL.MarkLabel(endOfMthd);
    adderIL.Emit(OpCodes.Ret);
    
    return myTypeBldr.CreateType();
   }

   public static void Main() {

    Type adderType = BuildAdderType();

    object addIns = Activator.CreateInstance(adderType);

    object[] addParams = new object[2];

    Console.Write("Enter an integer value: ");
    addParams[0] = (object)Convert.ToInt32(Console.ReadLine());

    Console.Write("Enter another integer value: ");
    addParams[1] = (object)Convert.ToInt32(Console.ReadLine());

    Console.WriteLine("---");

    int adderResult = (int)adderType.InvokeMember("DoAdd",
                    BindingFlags.InvokeMethod,
                    null,
                    addIns,
                    addParams);

    if (adderResult != -1) {

        Console.WriteLine("{0} + {1} = {2}", addParams[0], addParams[1],
                  adderResult);
    } else {

        Console.WriteLine("One of the integers to add was greater than 100!");
    }		
   }
}

Comentários

Para definir a posição do rótulo dentro do fluxo, você deve chamar MarkLabel. A falha ao fazer isso causará um ArgumentException quando TypeBuilder.CreateType é chamado.

Isso é apenas um token e ainda não representa nenhum local específico dentro do fluxo.

Aplica-se a

Produto Versões
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.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.0 (package-provided), 2.1