2010-07-13 14 views
6

Tôi có một ứng dụng có khả năng bổ sung (MEF). Các plugin là WPF UserControls có dịch vụ nhập.Sự cố khi chỉ định các đại biểu trong vòng lặp

Người dùng có thể chọn plugin mong muốn từ menu chính của ứng dụng.

Để làm điều này, tôi sử dụng vòng lặp sau đây:

foreach(IToolPlugin Plugin in ToolPlugins) 
{ 
    Plugin.Init(); 
    MenuItem PluginMenuItem = Plugin.MenuItem; //New MenuItem but with Header set. 
    PluginMenuItem.Click += new RoutedEventHandler(delegate(object o, RoutedEventArgs e) { DoSomething(Plugin.Control);}); 
    PluginsMenu.Items.add(PluginMenuItem); 
} 

đó làm việc rất tốt cho một mục duy nhất. Nhưng ngay sau khi tôi có nhiều hơn 1 plugin, tất cả các menuitem thực hiện các đại biểu của vòng lặp cuối cùng. Hoặc ít nhất là với Plugin.Control của vòng lặp cuối cùng.

Tôi có thể sửa lỗi này bằng cách nào?
Cảm ơn bạn đã trợ giúp.

+5

Tôi yêu nhìn thấy nhiều các biến thể của câu hỏi này. – ChaosPandion

+0

@Chaos - trong trường hợp đó bạn nên bỏ phiếu để đóng;) – ChrisF

Trả lời

8

Trên mỗi lần lặp của vòng lặp, bạn phải "nắm bắt" giá trị của giá trị được lặp lại trước khi bạn sử dụng nó trong một đóng. Nếu không, Plugin trong mỗi đại biểu sẽ trỏ tới giá trị cuối cùng của Plugin thay vì giá trị được giữ khi hàm ẩn danh được tạo.

Bạn có thể đọc một sâu hơn trong giải thích từ Eric Lippert ở đây:

Closing over the loop variable considered harmful - Fabulous Adventures in Coding

Nói tóm lại, cách chính xác để viết vòng lặp foreach của bạn là:

foreach(IToolPlugin Plugin in ToolPlugins) 
{ 
    Plugin.Init(); 
    MenuItem PluginMenuItem = Plugin.MenuItem; 

    IToolPlugin capturedPlugin = Plugin; 

    PluginMenuItem.Click += 
     new RoutedEventHandler(delegate(object o, RoutedEventArgs e) { 
      DoSomething(capturedPlugin.Control); 
     }); 

    PluginsMenu.Items.add(PluginMenuItem); 
} 
+0

Tôi cho rằng bạn sẽ đưa liên kết bắt buộc vào các bài đăng trên blog của Eric về vấn đề này? (Kết thúc biến vòng lặp được coi là có hại.) –

+0

@Jon Skeet - Yep ... đang tìm cách liên kết. –

+0

Chúng ta nên có một rota cho câu hỏi này :) (Vì nó khó để tìm kiếm, tôi không nghĩ rằng nó có giá trị đóng nó như là một bản sao.) –

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