C# 如何在运行时删除Emit IL的最后几段
如何在运行时删除Emit IL的最后几段 我试图修改一千行代码中的一些逻辑,我想使用回滚IL方法添加新逻辑,避免更改以前的代码 简单的例子: 我希望删除Emit IL的最后几段,然后在C# 如何在运行时删除Emit IL的最后几段,c#,cil,emit,C#,Cil,Emit,如何在运行时删除Emit IL的最后几段 我试图修改一千行代码中的一些逻辑,我想使用回滚IL方法添加新逻辑,避免更改以前的代码 简单的例子: 我希望删除Emit IL的最后几段,然后在isSomeLogic为真时发出新的IL void Main() { DynamicMethod methodbuilder = new DynamicMethod("Deserialize" + Guid.NewGuid().ToString(), typeof(void), null); var
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
仅用于转发。无法删除已添加的操作码。相反,只是。。。不要添加它们?或者,您可以使用标签
和跳转操作;Ret
不需要位于方法的末尾;只要堆栈在ret处处于正确的高度,并且对于到特定位置的所有路径,堆栈高度都相同,则以下内容完全有效
- 做事
- 跳到X
- 标签:Y
- 多做事
- ret
- 标签:X
- 做更多的事情
- 跳转到Y
ILGenerator
仅用于转发。无法删除已添加的操作码。相反,只是。。。不要添加它们?或者,您可以使用标签
和跳转操作;Ret
不需要位于方法的末尾;只要堆栈在ret处处于正确的高度,并且对于到特定位置的所有路径,堆栈高度都相同,则以下内容完全有效
- 做事
- 跳到X
- 标签:Y
- 多做事
- ret
- 标签:X
- 做更多的事情
- 跳转到Y
操作码。Ret
发出,直到您知道是否要在返回之前发出更多代码?谢谢,我试图修改1000行代码中的一些逻辑,我想使用回滚IL方法添加新逻辑,避免更改以前的代码。由于这显然是在运行时发出的,为什么不推迟操作码.Ret
发出,直到您知道是否要在返回之前发出更多代码?谢谢,我尝试了修改1000行代码中的一些逻辑,我想使用回滚IL方法添加新逻辑,避免更改以前的代码。谢谢,我稍后会将此标记为“答案”,我试图在一千行代码中修改一些逻辑,我想使用回滚IL方法添加新逻辑,避免更改以前的代码。@ITWeiHan我的建议:更改以前的代码以使其适合场景;不管怎样,IL都很难做到正确;你最不想做的事就是侵入一些不太合适的东西;相信我:我去过那里(我确实去过很多次)谢谢!我会用你的方式,我见过简洁的IL写作,真是太神奇了。@ITWeiHan简洁的IL写作坦率地说是粗糙的,结构糟糕;我很想把它撕下来重新开始;protobuf net有更合理的解释,谢谢,我稍后会将此标记为答案,我试图在一千行代码中修改一些逻辑,我想使用回滚IL方法添加新逻辑,避免更改以前的代码。@我的建议是:更改以前的代码以使其适合场景;不管怎样,IL都很难做到正确;你最不想做的事就是侵入一些不太合适的东西;相信我:我去过那里(我确实去过很多次)谢谢!我会用你的方式,我见过简洁的IL写作,真是太神奇了。@ITWeiHan简洁的IL写作坦率地说是粗糙的,结构糟糕;我很想把它撕下来重新开始;protobuf网络具有更合理的发射