2013-02-23 8 views
5

ich eine sehr einfache Funktion erstellt haben, die die folgenden:Einfache generierte MSIL wirft „Operation die Laufzeit destabilisieren könnte“

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

Dies ist der Code, der die MSIL erzeugt. Warum wirft dies die Ausnahme "Operation könnte die Laufzeit destabilisieren"? Ich kann nichts falsch daran finden; es passt perfekt zu der in Reflector/Reflexil gesehenen Baugruppe.

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

Antwort

4

Ich fand, dass die neue Variable nicht ordnungsgemäß deklariert wurde.

Sie müssen die DeclareLocal(typeof(T))-Syntax verwenden, um eine neue lokale Variable zu deklarieren.

Der aktualisierte Code-Schnipsel ist wie folgt:

// 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: Dank Jon Skeet, die endgültige optimierte Code-Schnipsel wie folgt:

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

Alternativ erhalten die stloc los/ldloc ganz - du brauchst es nicht. –

Verwandte Themen