2013-02-23 6 views
5

Utworzyłem bardzo prostą funkcję, która wykonuje następujące operacje:Proste wygenerowany MSIL rzuca „Operacja mogłaby zdestabilizować wykonania”

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

Jest to kod, który generuje MSIL. Dlaczego to rzuca "Operacja może zdestabilizować wyjątek środowiska wykonawczego"? Nie widzę w tym nic złego; idealnie pasuje do zespołu widocznego w Reflectorze/Reflexilu.

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

Odpowiedz

4

Znalazłem, że nowa zmienna nie została poprawnie zadeklarowana.

Musisz użyć składni DeclareLocal(typeof(T)), aby zadeklarować nowy lokalny var.

Zaktualizowana fragment kodu jest następujący:

// 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: Dzięki Jon Skeet, ostateczny kod zoptymalizowany fragment przedstawia się następująco:

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

Alternatywnie pozbyć stloc/ldloc całkowicie - nie potrzebujesz tego. –