如何在运行时删除 Emit IL 的最后几段
How to remove the last few segments of Emit IL at runtime
如何在运行时删除 Emit IL 的最后几段
我试图修改几千行代码中的一些逻辑,我想使用回滚 IL 的方式添加新逻辑,避免更改以前的代码。
简单例如:
希望去掉Emit IL的最后几段,然后在isSomeLogic
为真时发出新的il。
void Main()
{
DynamicMethod methodbuilder = new DynamicMethod("Deserialize" + Guid.NewGuid().ToString(), typeof(void), null);
var il = methodbuilder.GetILGenerator();
il.Emit(OpCodes.Ldstr, "Hello World");
Type[] types = new Type[1]{typeof(string)};
MethodInfo method = typeof(Console).GetMethod("WriteLine", types);
il.Emit(OpCodes.Call, method);
il.Emit(OpCodes.Ret);
// do some thing...
var isSomeLogic = true;
if( isSomeLogic ){
//remove the il OpCodes.Ret and add new logic Emit
il.Emit(OpCodes.Ret);
}
var func = (Action)methodbuilder.CreateDelegate(typeof(Action));
func();
}
ILGenerator
只是前锋。您不能删除 您添加的操作码。相反,只是......不添加它们?或者,您可以使用 Label
和跳转操作; Ret
不需要位于方法的 end 处;以下是完全有效的,只要堆栈在 ret 处的高度正确,并且堆栈高度对于到特定位置的所有路径都是相同的。
- 做事
- 跳转到 X
- 标签:Y
- 做更多事情
- ret
- 标签:X
- 做更多的事情
- 跳转到 Y
如何在运行时删除 Emit IL 的最后几段
我试图修改几千行代码中的一些逻辑,我想使用回滚 IL 的方式添加新逻辑,避免更改以前的代码。
简单例如:
希望去掉Emit IL的最后几段,然后在isSomeLogic
为真时发出新的il。
void Main()
{
DynamicMethod methodbuilder = new DynamicMethod("Deserialize" + Guid.NewGuid().ToString(), typeof(void), null);
var il = methodbuilder.GetILGenerator();
il.Emit(OpCodes.Ldstr, "Hello World");
Type[] types = new Type[1]{typeof(string)};
MethodInfo method = typeof(Console).GetMethod("WriteLine", types);
il.Emit(OpCodes.Call, method);
il.Emit(OpCodes.Ret);
// do some thing...
var isSomeLogic = true;
if( isSomeLogic ){
//remove the il OpCodes.Ret and add new logic Emit
il.Emit(OpCodes.Ret);
}
var func = (Action)methodbuilder.CreateDelegate(typeof(Action));
func();
}
ILGenerator
只是前锋。您不能删除 您添加的操作码。相反,只是......不添加它们?或者,您可以使用 Label
和跳转操作; Ret
不需要位于方法的 end 处;以下是完全有效的,只要堆栈在 ret 处的高度正确,并且堆栈高度对于到特定位置的所有路径都是相同的。
- 做事
- 跳转到 X
- 标签:Y
- 做更多事情
- ret
- 标签:X
- 做更多的事情
- 跳转到 Y