2013-02-23 18 views
5

「操作は、ランタイムを不安定にする可能性」がスローされます。なぜこれは "オペレーションがランタイムを不安定にする可能性がある"という例外をスローしますか?私はそれに何か間違った点を見つけることはできません。 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

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

新しいローカル変数を宣言するには、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 }); 

編集:ジョンスキートにおかげで、最終的に最適化されたコードスニペットは、次のとおりです。次のように

更新されたコードスニペットがある代わりに

// 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 }); 
+0

、stlocを取り除きます/ ldlocは完全に - あなたはそれを必要としません。 –

関連する問題