2013-02-23 19 views
5

tôi đã tạo ra một chức năng rất đơn giản nào sau đây:đơn giản tạo ra MSIL ném "Operation có thể làm mất ổn định thời gian chạy"

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

Đây là mã mà tạo ra MSIL. Tại sao điều này lại ném "Hành động có thể làm mất ổn định thời gian chạy" ngoại lệ? Tôi không thể phát hiện ra bất cứ điều gì sai trái với nó; nó phù hợp với lắp ráp được thấy trong Reflector/Reflexil một cách hoàn hảo.

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

Trả lời

4

Tôi thấy rằng biến mới chưa được khai báo đúng cách.

Bạn cần sử dụng cú pháp DeclareLocal(typeof(T)) để khai báo biến địa phương mới.

Đoạn mã được cập nhật như sau:

// 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: Nhờ Jon Skeet, trận chung kết tối ưu hóa đoạn mã như sau:

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

Ngoài ra, thoát khỏi stloc/ldloc hoàn toàn - bạn không cần nó. –

Các vấn đề liên quan