5

次のことを行う非常に単純な関数を作成しました。

    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 });
4

1 に答える 1

4

新しい変数が正しく宣言されていないことがわかりました。

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 });
于 2013-02-23T15:02:22.040 に答える