c# - 简单生成的 MSIL 抛出 "Operation could destabilize the runtime"

标签 c# .net cil dynamicmethod

我创建了一个非常简单的函数来执行以下操作:

    public static object[] ToArray(int ID) {
        return new object[4];
    }

这是生成 MSIL 的代码。为什么这会抛出“操作可能会破坏运行时的稳定性”异常?我看不出有什么问题;它与 Reflector/Reflexil 中看到的组件完美匹配。

    // create method
    Type arrayType = typeof(object[]);
    Type intType = typeof(int);
    DynamicMethod dm = new DynamicMethod(methodName, arrayType, new Type[] { intType });
    ILGenerator il = dm.GetILGenerator();

    // create the array -- object[]
    il.Emit(OpCodes.Ldc_I4, 4);
    il.Emit(OpCodes.Newarr, typeof(object));
    il.Emit(OpCodes.Stloc_0);

    // return the array
    il.Emit(OpCodes.Ldloc_0); 
    il.Emit(OpCodes.Ret);

    return dm;
    object result = dm.Invoke(null, new object[] { 1 });

最佳答案

我发现新变量没有正确声明。

您需要使用 DeclareLocal(typeof(T)) 语法来声明一个新的局部变量。

更新后的代码片段如下:

    // create method
    Type arrayType = typeof(object[]);
    Type intType = typeof(int);
    DynamicMethod dm = new DynamicMethod(methodName, arrayType, new Type[] { intType });
    ILGenerator il = dm.GetILGenerator();

    // create the array -- object[]
    LocalBuilder arr = il.DeclareLocal(arrayType);
    il.Emit(OpCodes.Ldc_I4, 4);
    il.Emit(OpCodes.Newarr, typeof(object));
    il.Emit(OpCodes.Stloc, arr);  // <-- don't use direct addresses, use refs to LocalBuilder instead

    // return the array
    il.Emit(OpCodes.Ldloc, arr); // <-- don't use direct addresses, use refs to LocalBuilder instead
    il.Emit(OpCodes.Ret);

    return dm;
    object result = dm.Invoke(null, new object[] { 1 });

编辑:感谢Jon Skeet,最终优化后的代码片段如下:

    // create method
    Type arrayType = typeof(object[]);
    Type intType = typeof(int);
    DynamicMethod dm = new DynamicMethod(methodName, arrayType, new Type[] { intType });
    ILGenerator il = dm.GetILGenerator();

    // create the array -- object[]
    LocalBuilder arr = il.DeclareLocal(arrayType);
    il.Emit(OpCodes.Ldc_I4, 4);
    il.Emit(OpCodes.Newarr, typeof(object));

    // return the array
    il.Emit(OpCodes.Ret);

    return dm;
    object result = dm.Invoke(null, new object[] { 1 });

关于c# - 简单生成的 MSIL 抛出 "Operation could destabilize the runtime",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15041803/

相关文章:

c# - 如何从不同的输入插入

c# - 如何使用 DataContract 添加 XML 属性

c# - 澄清 IL 生成的引用字符串的代码

c# - 为什么编译器添加了一个不需要的局部变量

java - 当JSON包含Json.Net C#生成的$ref和$id时,如何在Java中反序列化

c# - BindingSource.Filter 最大长度

c# - 为什么子类变量先于父类成员变量初始化

c# - 我什么时候启动和处置我的用户控件?

c# - 为什么 callvirt IL 指令会导致虚方法中的递归调用?

c# - 使用 Linq 表达式返回默认 DateTime