动态方法,在本地存储返回值

时间:2013-04-09 23:59:33

标签: c# dynamic il

我遇到了动态方法的一些问题。此方法的(伪)IL-Code看起来像这样

var localB = dynMethodGen.DeclareLocal(typeof(Runtime.IntegerObject));
dynMethodGen.Emit(Ldc_I8, 2);
dynMethodGen.Emit(Newobj, Runtime.IntegerObject.Constructor);
dynMethodGen.Emit(ldstr, "a");
dynMethodGen.Emit(call, GlobalDeclaratorManager.SetMethod);
dynMethodGen.Emit(ldstr, "a");
dynMethodGen.Emit(call, GlobalDeclaratorManager.GetMethod);
dynMethodGen.Emit(Stloc, localB);

使用此代码我有以下问题:最终的Stloc导致异常: System.Security.VerificationException:Dieser Vorgang kann die Laufzeit destabilisieren。 (用英语表示运行时可能不稳定)。

我在堆栈不正确之前就已经有了这个,但在这种情况下堆栈是正确的。最后用一个简单的Pop替换Stloc一切正常,除了该值没有存储在语言环境中。

Get和Set方法如下所示:

        public static GenericObject getGlobal(string name)
        {
            return mDeclarators[name];
        }

        public static void setGlobal(GenericObject value, string name)
        {
            mDeclarators[name] = value;
        }

还可以用另一个调用SetMethod来替换Stloc,这些值是正确传递的。

我错过了某种限制吗?我可以将函数的返回值存储在语言环境中吗?

1 个答案:

答案 0 :(得分:3)

你要做的是

setGlobal(new IntegerObject(2), "a");

IntegerObject localB = getGlobal("a");

声明getGlobal返回GenericObject个实例。

除非GenericObject类扩展IntegerObject类,否则不能将GenericObject实例的引用存储在IntegerObject变量中。 C#编译器会给你以下错误信息:

  

无法将类型'GenericObject'隐式转换为'IntegerObject'

假设IntegerObject扩展GenericObject,解决方案是添加类似

的强制转换
IntegerObject localB = (IntegerObject)getGlobal("a");

IntegerObject localB = getGlobal("a") as IntegerObject;