2009-11-22 51 views
8

Tôi đang cố gắng gọi một phương thức nội bộ từ một phương thức được tạo động. Mã il rất đơn giản: ldarg_0, callvirt, ret.Có thể gọi phương thức nội bộ từ một phương thức động trong .NET không?

Thực hiện phương thức không thành công với TypeLoadException nói rằng nó không thể tải loại mà phương thức nội bộ được xác định.

Khi tôi nghĩ về điều này, điều này có vẻ hợp lý, vì cụm máy chủ lưu trữ phương thức động không phải là bạn của phương thức khai báo kiểu của phương thức.

Tuy nhiên, tôi đã mong đợi phương pháp động vẫn hoạt động, giống như Delegate.CreateDelegate hoạt động. Sau khi tất cả, tôi đã quản lý để có được MethodInfo của phương pháp nội bộ, do đó, các rào cản quyền được phía sau tôi.

Dù sao, câu hỏi là "có thể gọi phương thức nội bộ từ phương thức được tạo động không?"

Cảm ơn.

EDIT:

Đây là một mẫu mã đơn giản chứng minh vấn đề:

using System; 
using System.Linq.Expressions; 
using System.Reflection; 
using System.Reflection.Emit; 

namespace A 
{ 
    internal class Data 
    { 
    internal string String { get; set; } 
    } 

    public static class Program 
    { 
    public static void Main() 
    { 
     Expression<Func<Data, string>> expr = x => x.String; 
     var getterInfo = ((PropertyInfo)((MemberExpression)expr.Body).Member).GetGetMethod(true); 
     var getter1 = (Func<Data, string>)Delegate.CreateDelegate(typeof(Func<Data, string>), getterInfo); 
     var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }); 
     var gen = dm.GetILGenerator(); 
     gen.Emit(OpCodes.Ldarg_0); 
     gen.Emit(OpCodes.Castclass, typeof(Data)); 
     gen.Emit(OpCodes.Callvirt, getterInfo); 
     gen.Emit(OpCodes.Ret); 
     var getter2 = (Func<object, object>)dm.CreateDelegate(typeof(Func<object, object>)); 

     var data = new Data() { String = "Hello" }; 
     var str1 = getter1(data); 
     var str2 = getter2(data); 
    } 
    } 
} 

Trong đoạn code tôi tạo ra hai đại biểu dụ mở để truy cập tài sản Data.String dụ:

  • loại getter1 an toàn sử dụng Delegate.CreateDelegate
  • loại uns afe getter2 sử dụng DynamicMethod

Loại ủy nhiệm an toàn được tạo bởi Delegate.CreateDelegate hoạt động, trong khi loại sử dụng DynamicMethod không thành công với TypeLoadException.

Lưu ý rằng tôi không muốn thực hiện phương pháp an toàn kiểu, vì ngữ cảnh mà trình tạo được tạo không phải là chung chung. Tất nhiên, tôi có thể giải quyết vấn đề này, nhưng câu hỏi bây giờ là của hiệu trưởng - tại sao DynamicMethod không thành công khi Delegate.CreateDelegate thành công?

+0

Một TypeLoadException ngụ ý rằng không thể tìm thấy hội đồng - trình xem nhật ký tổng hợp nói gì? –

+0

Nhật ký kết hợp trống. Không có vấn đề gì để lắp ráp. Tất cả các hội đồng liên quan đều nằm trong cùng một thư mục. – mark

+0

@JeremyMcGee là đúng. Lấy danh sách các assembly được nạp trong AppDomain trong chế độ debug và kiểm tra là assembly đích ở đó. Ngoài ra, tốt hơn nên đặt mã của bạn ở đây để kiểm tra. –

Trả lời

6

Nó sẽ hoạt động nếu bạn bỏ qua kiểm tra mức hiển thị.

Thay đổi dòng này

var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }, true); 

Xem msdn: (. Đặc biệt là bảng với tất cả các quy tắc)

Đây là từ doco trên các nhà xây dựng.

Loại restrictedSkipVisibility: System.Boolean đúng để bỏ qua JIT kiểm tra tầm nhìn trên các loại và các thành viên truy cập bởi MSIL của phương pháp năng động , với hạn chế này: mức sự tin tưởng của các hội đồng rằng chứa những các loại và thành viên phải là bằng hoặc nhỏ hơn mức độ tin cậy của ngăn xếp cuộc gọi phát ra phương thức động ; ngược lại, sai.

+0

DynamicMethod không có trong tiêu chuẩn .net, bất kỳ cách nào để thực hiện điều này trong tiêu chuẩn .net? – trampster

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