2010-06-08 38 views
6

Trong các khuôn khổ .NET 2.0-3.5, LCG (hay còn gọi là lớp DynamicMethod) là một cách tốt để phát ra các phương thức nhẹ khi chạy khi không có cấu trúc lớp nào cần thiết để hỗ trợ chúng. Trong .NET 4.0, các cây biểu hiện hỗ trợ các lệnh và khối, và như vậy xuất hiện để cung cấp đầy đủ chức năng để xây dựng chỉ là về bất kỳ chức năng nào bạn có thể yêu cầu từ một phương thức như vậy, và có thể được xây dựng theo một cách dễ dàng hơn và an toàn hơn nhiều hơn là trực tiếp phát ra mã op CIL. (Tuyên bố này được sinh ra từ thử nghiệm ngày nay của việc chuyển đổi một số mã LCG phức tạp nhất của chúng tôi để sử dụng xây dựng cây biểu hiện và biên dịch thay thế.)Thế hệ mã nhẹ (LCG) có bị chết không?

Vì vậy, có lý do gì để sử dụng LCG trong bất kỳ mã mới nào không? Có cái gì nó có thể làm mà cây biểu hiện không thể? Hay bây giờ nó là một chức năng 'chết'?

Trả lời

1

Vâng, câu hỏi này khá cũ và tôi đang đợi tf get để hoàn thành ... vì vậy tôi sẽ tự trả lời.

Có, LCG đã chết trong hầu hết các trường hợp.

Chúng tôi đã từng sử dụng LCG một chút và giờ đây tất cả đã được chuyển đổi để sử dụng cây biểu thức thay thế. Chúng dễ xây dựng hơn nhiều, mã dễ bảo trì và gỡ lỗi dễ dàng hơn, và các thông báo lỗi thường có nhiều thông tin hơn 'Thao tác có thể làm mất ổn định thời gian chạy' khi bạn gặp sự cố trong quá trình phát triển.

Nhưng, có lẽ quan trọng nhất, các cây biểu thức được tổng hợp theo cách mà Reflection.Emit thì không. Điều này có nghĩa là kiến ​​trúc của các thành phần được sử dụng để tạo mã thời gian chạy có thể có nhiều mô đun hơn và thậm chí cho phép các plugin mở rộng khung công tác tạo mã.

Điều tôi đã tìm thấy được hỗ trợ bởi Reflection.Emit không được hỗ trợ trực tiếp trong cây biểu thức đang đặt các trường .initonly. Này, tuy nhiên, có thể đạt được bằng cách sử dụng một lớp helper ít và gọi nó trong cây biểu hiện, ví dụ như chúng ta sử dụng là dưới đây:

internal static class FieldHelper 
{ 
    public static TTarget AssignInitOnlyField<TTarget, TField>(
     TTarget target, string fieldName, TField value) 
    { 
     var field = target.GetType().GetField(
      fieldName, 
      BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic); 
     var boxed = (object)target; // required for value type support 
     field.SetValue(boxed, value); 
     return (TTarget)boxed; 
    } 
} 

Nó đáng nói là người xuống phía của việc sử dụng cây biểu hiện khá hơn LCG là việc xây dựng và biên dịch các cây biểu thức chắc chắn chậm hơn so với việc phát ra các mã op nguyên trực tiếp. Giả sử bạn đang lưu vào bộ nhớ đệm các phương thức được biên dịch, đây không phải là vấn đề quan trọng, nhưng đó là một lý do khiến bạn vẫn có thể buộc bạn phải sử dụng LCG.

+0

Câu trả lời rõ ràng là không. LCG chính xác là hữu ích vì nó cho phép biên dịch IL trong thời gian chạy, làm cho nó hoạt động hiệu quả hơn rất nhiều. Nếu bạn không cần mã được xây dựng để được nhanh chóng, bạn không cần nó. Vì vậy, về cơ bản họ LCG vẫn có niche của nó. – Benja

3

Không có điểm nào trong việc xây dựng CIL trực tiếp mà không có bất kỳ bước trung gian nào. Nhưng nó là hoàn toàn tốt đẹp để sử dụng ngôn ngữ trung gian của riêng bạn đang nhắm mục tiêu IL ở cuối. Cây biểu hiện, vv, là không đủ - nó chỉ là một ngôn ngữ, trong khi trong khi thực hiện DSL bạn cần nhiều ngữ nghĩa khác nhau.

Bạn có thể phát ra mã không an toàn (với nhiều ldftns và giống nhau), bạn có thể phát ra cuộc gọi đuôi (không chắc chắn nếu có thể với biểu thức), cuộc gọi không ảo đến phương pháp ảo, bạn có thể xây dựng hiệu quả và nhảy, vv Biểu thức cây rất hạn chế mà tôi chỉ đơn giản là không thể hiểu làm thế nào họ có thể được so sánh với một CIL thô.

0

LCG đề cập đến các phương pháp có thể được thu thập sau khi chúng vượt quá phạm vi. Biểu thức LINQ sử dụng LCG hoặc phản xạ thông thường phát ra ... Vì vậy LCG chắc chắn không chết. Ngoài ra các biểu thức LINQ không hỗ trợ mọi thứ như tham số ref, ldtoken, các phương thức mẫu, thuộc tính, vv

0

Cây biểu thức chắc chắn là một cách để tận dụng tối đa mã thời gian chạy.Tuy nhiên, bạn nên nhận thức rõ ràng rằng nó bị giới hạn và không cung cấp cho bạn quyền truy cập toàn bộ sức mạnh của ngôn ngữ MSIL. Vì vậy, LGC và ILGenerator chắc chắn sẽ ở lại cho các nhiệm vụ đòi hỏi nhiều hơn.

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