C# 反射 : If . .. 否则?

标签 c# reflection reflection.emit system.reflection memory-address

我目前正面临与运营商有关的新问题。使用以下代码,我想生成与在 C# 中使用 if ... else 对时相同的输出。

var method = new DynamicMethod("dummy", null, Type.EmptyTypes);
var g = method.GetILGenerator();

g.Emit(OpCodes.Ldstr, "string");
g.Emit(OpCodes.Ldstr, "string");
g.Emit(OpCodes.Call, typeof(String).GetMethod("op_Equality", new Type[]{typeof(string), typeof(string)}));
g.Emit(OpCodes.Ldc_I4, 0);
g.Emit(OpCodes.Ceq);
g.Emit(OpCodes.Brtrue_S, );

var action = (Action)method.CreateDelegate(typeof(Action));
action();

Console.Read();

我的问题是:

  1. 如何获取指令的地址以将其作为分支操作码的参数传递?
  2. BRBR_SBrtrueBrtrue_SBrfalse有区别吗code> 和 Brfalse_S 以及类似的指令?

谢谢。

最佳答案

  1. 您可以使用 DefineLabel 的组合和 MarkLabel确定目标位置的方法 分支。为此,声明您需要的标签 - 类似于 等于notequal。然后你可以在你的 IL 中标记点 标签应该存在。完成后,您可以设置 到此标签的分支指令的目标。

    // Define labels
    Label equal = g.DefineLabel();
    Label notEqual = g.DefineLabel();
    Label endOfMethod = g.DefineLabel();
    // your logic here
    g.Emit(OpCodes.Brtrue_S, equal);
    g.MarkLabel(equal);
    // some code if they are equal
    g.MarkLabel(notEqual);
    // some code if they are not equal
    g.MarkLabel(endOfMethod); // this marks the return point
    g.Emit(OpCodes.Ret);
    
  2. BrBrtrueBrfalse的区别及其_S 同行的是跳跃的长度。 _S 表示缩写; 目标指令是距下一条指令的 1 字节有符号偏移量。在标准(非短)形式中,目标是 由 4 字节偏移量表示。

关于C# 反射 : If . .. 否则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11139241/

相关文章:

c# - 组合框边框样式

c# - 为什么 Guid 不是 c# 中的对象?

c# - 使用反射将 IDbSet<T> 的属性复制到另一个同名的 List<T> 类的属性?

c# - IL Emit TypeBuilder 和解析引用

c# - 在 C# 中获取属性值(反射)的最快方法

c# - 如何使用 C# 制作几个不同的列表?

c# - 将日期时间字符串转换为 Utc

c# - 当文件类型和文件名未知时,通过 url 在 c# 中下载文件

c# - Activator.CreateInstance 在这种情况下的优势

c# - 当通过 TypeBuilder.CreateType 实现具有参数为 'in' 的方法的接口(interface)时,抛出 TypeLoadException