修改方法的IL代码的更好方法是什么?

时间:2016-08-07 11:47:02

标签: c# code-generation reflection.emit

我需要将方法call中的A()指令从this.B()替换为this.C()。现在我使用this helper获取方法A()的IL指令,然后替换call指令,然后使用IL生成器手动发出所有指令。 注意:有一个带有帮助者的nuget - Mono.Reflection

用于演示我需要的部分代码:

var emitter = methodBuilder.GetILGenerator();
foreach (var cmd in baseMethodInfo.GetInstructions())
{
    if (cmd.Operand == null)
        emitter.Emit(cmd.OpCode);
    else
    {
        switch (cmd.OpCode.OperandType)
        {
            case OperandType.InlineMethod:
            {
                var currentMethodInfo = cmd.Operand as MethodInfo;
                //check that it's this.B() and get this.C() then
                var methodToReplace = installedMethods.SingleOrDefault(m => m.MethodInfo == currentMethodInfo);
                if (methodToReplace != null)
                    emitter.EmitCall(cmd.OpCode, methodToReplace.MethodBuilder, null);
                else
                    emitter.EmitCall(cmd.OpCode, currentMethodInfo, null);
                break;
            }
            ...
        }
    }
}

但我想有人已经实现了类似的东西,我想使用它,因为它很可能是一种更好,更安全的方式。我知道Mono.Cecil提供了替换教学的能力,但我知道它只适用于asembly loading time,但我需要runtime

1 个答案:

答案 0 :(得分:0)

与塞西尔一起做是最简单的方法。正如svick写的那样,即使你需要替换哪种方法的信息在运行时出现(当然,只要这种方法满足你的性能要求),你也可以这样做。

如果您想查看其他选项,请查看this answer