2013-02-23 2 views
5

Я создал очень простую функцию, которая выполняет следующие действия:Простой генерируется MSIL кидает «Операция может дестабилизировать выполнения»

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

Я обнаружил, что новая переменная не была объявлена ​​должным образом.

Для объявления нового локального var необходимо использовать синтаксис 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 }); 

Edit: Благодаря Jon тарелочкам, окончательный оптимизированный фрагмент кода выглядит следующим образом:

// 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 целиком - вам это не нужно. –