2013-02-23 14 views
5

Ho creato una semplice funzione che esegue le operazioni seguenti:semplice generato MSIL getta "Operazione potrebbe destabilizzare il runtime"

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

Questo è il codice che genera il codice MSIL. Perché questo lancia l'eccezione "Operazione potrebbe destabilizzare il runtime"? Non riesco a individuare nulla di sbagliato in esso; corrisponde perfettamente al gruppo visto in 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 }); 

risposta

4

Ho trovato che la nuova variabile non è stata dichiarata correttamente.

È necessario utilizzare la sintassi DeclareLocal(typeof(T)) per dichiarare una nuova var locale.

Il frammento di codice aggiornato è il seguente:

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

Edit: Grazie a Jon Skeet, il frammento di codice ottimizzato finale è la seguente:

// 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

In alternativa, sbarazzarsi del stloc/ldloc interamente: non ne hai bisogno. –

Problemi correlati