修改方法的 IL 代码的更好方法是什么?
What is a better way to modify IL code of the method?
我需要将方法 A()
中的 call
指令从 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
.
用 Cecil 做是最简单的方法。正如 svick 所写,即使您需要替换的方法的信息在运行时出现(当然只要此方法满足您的性能要求),您也可以这样做。
但是如果你想检查其他选项,请检查this answer。
我需要将方法 A()
中的 call
指令从 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
.
用 Cecil 做是最简单的方法。正如 svick 所写,即使您需要替换的方法的信息在运行时出现(当然只要此方法满足您的性能要求),您也可以这样做。
但是如果你想检查其他选项,请检查this answer。