C# 修改方法的IL代码的更好方法是什么?
我需要将方法C# 修改方法的IL代码的更好方法是什么?,c#,code-generation,reflection.emit,C#,Code Generation,Reflection.emit,我需要将方法A()中的call指令从this.B()替换为this.C()。现在我用来获取方法A()的IL指令,然后替换call指令,然后使用IL生成器手动发出所有指令。 注意:该助手有一个nuget- 代码的一部分,用于演示我需要的内容: var emitter = methodBuilder.GetILGenerator(); foreach (var cmd in baseMethodInfo.GetInstructions()) { if (cmd.Operand == null
A()
中的call
指令从this.B()
替换为this.C()
。现在我用来获取方法A()
的IL指令,然后替换call
指令,然后使用IL生成器手动发出所有指令。
注意:该助手有一个nuget-
代码的一部分,用于演示我需要的内容:
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加载时间
,但我需要运行时
使用Cecil进行替换是最简单的方法。正如svick所写,即使需要替换的方法的信息在运行时出现(当然,只要该方法满足您的性能要求),您也可以这样做
但是如果您想检查其他选项,请检查。使用Cecil进行检查是最简单的方法。正如svick所写,即使需要替换的方法的信息在运行时出现(当然,只要该方法满足您的性能要求),您也可以这样做
但是如果您想检查其他选项,请检查。为什么需要“运行时”?看起来你正在创建一个新的方法,难道你不能使用Cecil创建一个新的程序集,其中只包含你需要的方法吗?不幸的是,我得到了在运行时应该替换哪些方法的信息<例如,code>this.B()和
this.C()
。为什么会出现这个问题?您可以在运行时创建并加载程序集。可能的性能问题。在我替换我将需要生成的代码的每个地方(在不同的方法中相同),保存并加载程序集。使用reflection.emit,我可以声明单个程序集。但是我没有考虑建议的方法。我可以试一下,测试一下性能。谢谢。程序集加载时间是运行时。如果您试图在加载程序集后执行此操作,则很可能太晚,必须在即时编译器从IL生成机器代码之前执行此操作。您为什么需要“运行时”?看起来你正在创建一个新的方法,难道你不能使用Cecil创建一个新的程序集,其中只包含你需要的方法吗?不幸的是,我得到了在运行时应该替换哪些方法的信息<例如,code>this.B()和this.C()
。为什么会出现这个问题?您可以在运行时创建并加载程序集。可能的性能问题。在我替换我将需要生成的代码的每个地方(在不同的方法中相同),保存并加载程序集。使用reflection.emit,我可以声明单个程序集。但是我没有考虑建议的方法。我可以试一下,测试一下性能。谢谢。程序集加载时间是运行时。如果您试图在加载程序集后执行此操作,则很可能太晚,必须在即时编译器从IL生成机器代码之前执行此操作。