简体   繁体   中英

What is a better way to modify IL code of the method?

I need to replace call instruction in the method A() from this.B() to this.C() . Now I use this helper to get IL instructions of Method A() then replace call instruction and then use IL generator to emit all instructions manually. Note: There is a nuget with that helper - Mono.Reflection

Part of the code to demonstrate what I need:

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;
            }
            ...
        }
    }
}

But I guess somebody already implement something like that and I want to use it because most likely it's a more better and safety way. I know Mono.Cecil gives ability to replace instruction but as I know it's only for asembly loading time but I need runtime .

Do it with Cecil is the easiest way. And as svick wrote, you can do it even if the info of which method you need to replace is coming in runtime (of-course just if this method meet your performance requirements).

But if you want to check other options, please check this answer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM