如何在 Reflection.Emit 中使用条件

How to use conditional in Reflection.Emit

您好,我正在使用 Reflection.Emit 生成 class,我想知道您如何使用 brfalse 命令来实现 conditionals

具体来说,我不知道如何将 IL 转换为 OPCODES brfalse.s 命令。

我的方法具有以下形式:

object MyMethod() { if(isTransaction) //isTransaction is a bool property return Method1(); else return Method2(); }

条件

        IL_0000: ldarg.0      // this
        IL_0001: call         instance bool RediusTests.DaemonBase::get_IsTransaction()
        IL_0006: brfalse.s    IL_0020    //how is this translated within opcodes?

第一个分支:

        IL_0008:ldarg_0
        IL_.......          ///INSTRUCTIONS
        IL_......
        IL_001f:ret

第二支:

        IL_0020:ldarg_0     //How do i specify with OPCODES to jump here?????
        IL_.......          
        IL_......
        IL_001f:ret

对于第一个片段,brfalse.s 的参数是什么?

        ilgen.Emit(OpCodes.Ldarg_0);
        ilgen.Emit(OpCodes.Call, getIsTransaction);
        ilgen.Emit(OpCodes.Brfalse,);  //what do i put here in the overload?

正如您在最后一个片段中看到的,最后一行,我应该在 ilgen.Emit 的重载中放入什么?什么都没有,20 或者是否有一些其他代码可以翻译成 IL_0020?

另外,指令的地址不是在每个运行的程序中存储在不同的内存地址吗?它不能在以后的执行中从IL0020变为IL00xx吗?

P.S 在收到一些全面的答案后,这是我目前的版本:

        ILGenerator ilgen = newMethod.GetILGenerator();
        Label falseLabel = ilgen.DefineLabel();
        Label continueLabel = ilgen.DefineLabel();

        ilgen.Emit(OpCodes.Ldarg_0);       
        ilgen.Emit(OpCodes.Call, getIsTransaction);
        ilgen.Emit(OpCodes.Brtrue,continueLabel);   //branching

        ilgen.MarkLabel(continueLabel);    //true branch
        ----instructions------
        ilgen.Emit(OpCodes.Ret);
        ilgen.Emit(OpCodes.Br,continueLabel);

        ilgen.MarkLabel(falseLabel);     //false branch
        --instructions----
        ilgen.Emit(OpCodes.Ret);

您永远不必显式处理代码地址。 为了跳转,你需要定义标签:

Label falseLabel = ilgen.DefineLabel();
Label continueLabel = ilgen.DefineLabel();

ilgen.Emit(OpCodes.Call, getIsTransaction);
ilgen.Emit(OpCodes.Brfalse, continueLabel);

// getIsTransaction returned true
...

ilgen.Emit(OpCodes.Br, continueLabel);

ilgen.MarkLabel(falseLabel);
// getIsTransaction returned false
...

ilgen.MarkLabel(continueLabel);