gpt4 book ai didi

c# - Reflection.Emit error Operation can destabilize runtime

转载 作者:行者123 更新时间:2023-12-02 22:38:06 24 4
gpt4 key购买 nike

我目前正在玩反射,我的短代码有问题:

public class Test
{
public Test()
{

}
public string Call()
{
string called = "Called";
return called;
}
}

和用法:

var method = new DynamicMethod("dummy", null, Type.EmptyTypes);
var g = method.GetILGenerator();

g.DeclareLocal(typeof(Object));
g.Emit(OpCodes.Newobj, typeof(Test).GetConstructor(Type.EmptyTypes));
g.Emit(OpCodes.Stloc, 0);
g.Emit(OpCodes.Nop);
g.Emit(OpCodes.Ldloc, 0);
g.Emit(OpCodes.Call, typeof(Test).GetMethod("Call", new Type[]{}));
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[]{ typeof(string) }));
g.Emit(OpCodes.Nop);
//g.Emit(OpCodes.Pop); - used in debugging
g.Emit(OpCodes.Ret);

var action = (Action)method.CreateDelegate(typeof(Action));
action();

Console.Read();

所以。我正在尝试在运行时创建新方法。在那个方法中,我正在创建新的空测试实例。然后,我试图将它设置为 object 类型的位置 (0)。然后我加载它并调用它的方法 Call 来获取字符串。最后,我试图将字符串结果显示在屏幕上。我的代码适用于“Ldloc_0”。当调用“Call”方法时会发生错误。有人知道如何解决这个问题吗?请帮忙。

最佳答案

Call(...) 并且是一个实例方法;尝试使用 CallVirt 而不是 OpCodes.CallConsole.WriteLine 是一个静态 方法,因此应该使用Call

如有疑问,只需为要发出的内容编写 C#,然后在反射器中查看即可。

请注意,Ldloc/0 后跟一个 call/callvirt 将无法验证 - 也应该在其中进行转换:

g.DeclareLocal(typeof(Object));
g.Emit(OpCodes.Newobj, typeof(Test).GetConstructor(Type.EmptyTypes));
g.Emit(OpCodes.Stloc, 0);
g.Emit(OpCodes.Ldloc, 0);
g.Emit(OpCodes.Castclass, typeof(Test));
g.Emit(OpCodes.Callvirt, typeof(Test).GetMethod("Call", new Type[] { }));
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine",
new Type[] { typeof(string) }));
g.Emit(OpCodes.Ret);

或更好:

g.DeclareLocal(typeof(Test));
g.Emit(OpCodes.Newobj, typeof(Test).GetConstructor(Type.EmptyTypes));
g.Emit(OpCodes.Stloc_0);
g.Emit(OpCodes.Ldloc_0);
g.Emit(OpCodes.Callvirt, typeof(Test).GetMethod("Call", new Type[] { }));
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine",
new Type[] { typeof(string) }));
g.Emit(OpCodes.Ret);

或最好的:

g.Emit(OpCodes.Newobj, typeof(Test).GetConstructor(Type.EmptyTypes));
g.Emit(OpCodes.Callvirt, typeof(Test).GetMethod("Call", new Type[] { }));
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine",
new Type[] { typeof(string) }));
g.Emit(OpCodes.Ret);

关于c# - Reflection.Emit error Operation can destabilize runtime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11137379/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com