2010-08-23 40 views
7

Tôi đang tạo một đối tượng trong thời gian chạy bằng cách sử dụng phản xạ phát ra. Tôi đã tạo thành công các trường, thuộc tính và nhận các phương thức thiết lập. Bây giờ tôi muốn thêm một phương thức. Vì lợi ích của sự đơn giản, giả sử phương thức chỉ trả về một số ngẫu nhiên. Làm cách nào để xác định nội dung phương thức?Cách tạo phương thức trong thời gian chạy bằng cách sử dụng Reflection.emit

EDIT:

Có, tôi đã xem tài liệu msdn cùng với các tài liệu tham khảo khác và tôi bắt đầu lấy đầu quấn quanh công cụ này. Tôi thấy ví dụ ở trên đang thêm và/hoặc đa bội như thế nào, nhưng điều gì sẽ xảy ra nếu phương pháp của tôi đang thực hiện các công cụ khác. Làm thế nào để tôi xác định rằng "công cụ" Giả sử tôi đã tạo ra các lớp dưới đây động, làm thế nào tôi sẽ tạo ra cơ thể của GetDetails() phương pháp?

class TestClass 
{ 
    public string Name { get; set; } 
    public int Size { get; set; } 

    public TestClass() 
    { 
    } 

    public TestClass(string Name, int Size) 
    { 
     this.Name = Name; 
     this.Size = Size; 
    } 

    public string GetDetails() 
    { 
     string Details = "Name = " + this.Name + ", Size = " + this.Size.ToString(); 
     return Details; 
    } 
} 

Trả lời

15

Bạn sử dụng MethodBuilder để xác định phương pháp. Để xác định nội dung phương thức, bạn gọi số GetILGenerator() để nhận số ILGenerator và sau đó gọi cho các phương thức Emit để phát ra các hướng dẫn IL riêng lẻ. Có một ví dụ về tài liệu MSDN cho MethodBuilder, và bạn có thể tìm thấy những ví dụ khác về cách sử dụng phản chiếu phát ra trên Using Reflection Emit page:

public static void AddMethodDynamically(TypeBuilder myTypeBld, 
            string mthdName, 
            Type[] mthdParams, 
            Type returnType, 
            string mthdAction) 
{ 
    MethodBuilder myMthdBld = myTypeBld.DefineMethod(
              mthdName, 
              MethodAttributes.Public | 
              MethodAttributes.Static, 
              returnType, 
              mthdParams); 
    ILGenerator ILout = myMthdBld.GetILGenerator(); 
    int numParams = mthdParams.Length; 
    for (byte x = 0; x < numParams; x++) 
    { 
     ILout.Emit(OpCodes.Ldarg_S, x); 
    } 
    if (numParams > 1) 
    { 
     for (int y = 0; y < (numParams - 1); y++) 
     { 
      switch (mthdAction) 
      { 
       case "A": ILout.Emit(OpCodes.Add); 
        break; 
       case "M": ILout.Emit(OpCodes.Mul); 
        break; 
       default: ILout.Emit(OpCodes.Add); 
        break; 
      } 
     } 
    } 
    ILout.Emit(OpCodes.Ret); 
} 

Có vẻ như bạn đang tìm kiếm các nguồn lực trên văn bản MSIL . Một tài nguyên quan trọng là lớp OpCodes, có thành viên cho mọi hướng dẫn IL. Tài liệu mô tả cách thức mỗi lệnh hoạt động. Một tài nguyên quan trọng khác là Ildasm hoặc Reflector. Những điều này sẽ cho phép bạn xem mã IL cho mã được biên dịch, điều này sẽ giúp bạn hiểu những gì IL bạn muốn viết. Chạy GetDetailsMethod của bạn thông qua Reflector và thiết lập ngôn ngữ để sản lượng IL:

.method public hidebysig instance string GetDetails() cil managed 
{ 
    .maxstack 4 
    .locals init (
     [0] string Details, 
     [1] string CS$1$0000, 
     [2] int32 CS$0$0001) 
    L_0000: nop 
    L_0001: ldstr "Name = " 
    L_0006: ldarg.0 
    L_0007: call instance string ConsoleApplication1.TestClass::get_Name() 
    L_000c: ldstr ", Size = " 
    L_0011: ldarg.0 
    L_0012: call instance int32 ConsoleApplication1.TestClass::get_Size() 
    L_0017: stloc.2 
    L_0018: ldloca.s CS$0$0001 
    L_001a: call instance string [mscorlib]System.Int32::ToString() 
    L_001f: call string [mscorlib]System.String::Concat(string, string, string, string) 
    L_0024: stloc.0 
    L_0025: ldloc.0 
    L_0026: stloc.1 
    L_0027: br.s L_0029 
    L_0029: ldloc.1 
    L_002a: ret 
} 

Để tạo ra một phương pháp như thế động, bạn sẽ cần phải gọi ILGenerator.Emit cho mỗi hướng dẫn:

ilGen.Emit(OpCodes.Nop); 
ilGen.Emit(OpCodes.Ldstr, "Name = "); 
ilGen.Emit(OpCodes.Ldarg_0); 
ilGen.Emit(OpCodes.Call, nameProperty.GetGetMethod()); 
// etc.. 

Bạn cũng có thể muốn tìm phần giới thiệu cho MSIL, chẳng hạn như: Introduction to IL Assembly Language.

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