我目前正面临与运营商有关的新问题。使用以下代码,我想生成与在 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();
我的问题是:
- 如何获取指令的地址以将其作为分支操作码的参数传递?
BR
和BR_S
、Brtrue
和Brtrue_S
、Brfalse
有区别吗code> 和Brfalse_S
以及类似的指令?
谢谢。
最佳答案
您可以使用
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);
Br
、Brtrue
、Brfalse
的区别及其_S
同行的是跳跃的长度。_S
表示缩写; 目标指令是距下一条指令的 1 字节有符号偏移量。在标准(非短)形式中,目标是 由 4 字节偏移量表示。
关于C# 反射 : If . .. 否则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11139241/