2013-04-10 26 views
8

Tôi muốn thực thi mã này vào chủ đề chính trong ứng dụng WPF và nhận được lỗi tôi không thể tìm ra những gì là sai:Không thể chuyển đổi phương pháp vô danh để gõ 'System.Delegate' vì nó không phải là một loại đại biểu

private void AddLog(string logItem) 
     { 

      this.Dispatcher.BeginInvoke(
       delegate() 
        { 
         this.Log.Add(new KeyValuePair<string, string>(DateTime.Now.ToLongTimeString(), logItem)); 

        }); 
     } 
+1

Hãy xem ở đây http://stackoverflow.com/questions/4936459/dispatcher-begininvoke-cannot-convert-lambda-to-system-delegate – MethodMan

Trả lời

20

Các hàm ẩn danh (biểu thức lambda và các phương thức ẩn danh) phải được chuyển đổi thành loại cụ thể ủy quyền, trong khi Dispatcher.BeginInvoke chỉ cần Delegate. Có hai lựa chọn cho điều này ...

  1. Tuy nhiên sử dụng BeginInvoke gọi hiện có, nhưng rõ loại đại biểu. Có nhiều cách tiếp cận khác nhau ở đây, nhưng tôi thường trích xuất các chức năng ẩn danh một tuyên bố trước đó:

    Action action = delegate() { 
        this.Log.Add(...); 
    }; 
    Dispatcher.BeginInvoke(action); 
    
  2. Viết một phương pháp khuyến nông trên Dispatcher mà mất Action thay vì Delegate:

    public static void BeginInvokeAction(this Dispatcher dispatcher, 
                Action action) 
    { 
        Dispatcher.BeginInvoke(action); 
    } 
    

    Sau đó, bạn có thể gọi phương pháp mở rộng với chuyển đổi tiềm ẩn

    this.Dispatcher.BeginInvokeAction(
         delegate() 
         { 
          this.Log.Add(...); 
         }); 
    

Tôi cũng khuyến khích bạn sử dụng biểu thức lambda thay vì phương pháp mang tính chất nói chung:

Dispatcher.BeginInvokeAction(() => this.Log.Add(...)); 

EDIT: Như đã nêu trong các ý kiến, Dispatcher.BeginInvoke đạt được một tình trạng quá tải trong .NET 4.5 mà phải mất một Action trực tiếp, vì vậy bạn không cần phương thức mở rộng trong trường hợp đó.

+0

Tôi đã có cùng một vấn đề và sau đó phát hiện ra rằng trong phiên bản 4.5 của .NET lớp Dispatcher đã bị quá tải (ví dụ: http://msdn.microsoft.com/en-us/library/hh199416(v=vs.110) .aspx) chấp nhận một ủy nhiệm Hành động, do đó, mã hoạt động mà không có đặc tả loại đại biểu rõ ràng. –

+0

@Mark: Nice - sẽ chỉnh sửa nội dung đó trong. –

2

Bạn cũng có thể sử dụng MethodInvoker cho việc này:

private void AddLog(string logItem) 
     { 
      this.Dispatcher.BeginInvoke((MethodInvoker) delegate 
      { 
       this.Log.Add(new KeyValuePair<string, string>(DateTime.Now.ToLongTimeString(), logItem)); 
      }); 
     } 
Các vấn đề liên quan