2009-04-22 70 views
33

Nếu bạn muốn tạo đại biểu tùy chỉnh, bạn sẽ sử dụng từ khóa đại biểu bằng chữ thường.Đại biểu so với từ khóa đại biểu

Bạn có thể làm gì với Lớp đại biểu thực tế? Điều này tốt cho điều gì? Không hiểu sự khác biệt chính xác.

Trả lời

34

Từ http://msdn.microsoft.com/en-us/library/system.delegate.aspx:

Lớp Delegate là lớp cơ sở với nhiều loại đại biểu. Tuy nhiên, chỉ hệ thống và trình biên dịch mới có thể lấy được một cách rõ ràng từ lớp Delegate hoặc từ lớp MulticastDelegate. Nó cũng không được phép lấy loại loại mới từ loại đại biểu. Lớp học Delegate không được coi là loại đại biểu; nó là một lớp được sử dụng để lấy được các loại đại biểu.

Hầu hết các ngôn ngữ thi hành một từ khóa delegate , và trình biên dịch cho những ngôn ngữ có thể bắt nguồn từ lớp MulticastDelegate; do đó, người dùng nên sử dụng từ khóa delegate do ngôn ngữ cung cấp.

+1

Tìm nạp tốt từ MSDN;) – Xian

+0

http://msdn.microsoft.com/en-us/library/system.delegate.aspx – Xian

2

Ưu điểm của lớp Delegate là lớp cơ sở cho tất cả các loại đại biểu trong .Net. Có một phương pháp mà có một thể hiện của lớp này cho phép bạn hoạt động chung trên tất cả các cách thức của các đại biểu. Đây là lý do hoạt động như ISynchronizedInvoke.Invoke sử dụng tham số này làm tham số.

+4

Cần lưu ý, tuy nhiên, yêu cầu một đại biểu theo cách này bị trễ và chậm hơn (theo đó). –

34

Từ khóa đại biểu dành cho trình biên dịch thực hiện một số phép thuật cho bạn. Khi bạn khai báo một đại biểu mới với một chữ ký tùy chỉnh,

  • trình biên dịch tạo một Loại mới cho bạn có nguồn gốc từ MulticastDelegate (lần lượt xuất phát từ Đại biểu).
  • trình biên dịch cho biết thêm một phương thức Invoke với chữ ký tùy chỉnh của bạn
  • tương tự các trình biên dịch thêm BeginInvoke và phương pháp EndInvoke cho loại hình mới này

Vì vậy, bây giờ khi bạn gọi delObject(args) - trình biên dịch chuyển đó để delObject.Invoke(args)

Lớp cơ sở đại biểu cung cấp một số chức năng như

  1. CreateDelegate (để lấy dele cổng gói một phương pháp tĩnh/ví dụ)
  2. DynamicInvoke (để gọi đại biểu với danh sách đối số - giới hạn muộn)
  3. Kết hợp và xóa (cho chuỗi đại biểu .. chuỗi nhiều đại biểu với nhau, ví dụ: nhiều đại biểu xử lý sự kiện cho một sự kiện)

Trình biên dịch C# cấm bạn bắt nguồn từ Đại biểu khám phá trong mã của bạn .. bạn phải sử dụng từ khóa đại biểu.

+1

+1: Đặc biệt đề cập đến "trình biên dịch tạo một Loại mới cho bạn bắt nguồn từ MulticastDelegate" . Vì vậy, theo mặc định, các đại biểu chúng tôi tạo ra là tất cả các đại biểu Đa phương tiện – A9S6

+0

Rõ ràng. Tôi thích câu trả lời của bạn. –

+0

'trình biên dịch tạo ra một kiểu mới cho bạn có nguồn gốc từ MulticastDelegate' Tôi không chắc chắn về điều này. Theo http://msdn.microsoft.com/en-us/library/system.delegate.aspx 'Tuy nhiên, chỉ có hệ thống và trình biên dịch mới có thể lấy được từ lớp Delegate hoặc từ lớp MulticastDelegate.' Xin lưu ý từ khóa" ** hoặc ** " –

1

Từ phối cảnh triển khai, lớp Delegate xác định các trường được sử dụng để biểu diễn con trỏ hàm của đại biểu và lớp MultiCastDelegate cung cấp chức năng đường cơ sở được sử dụng bởi các sự kiện. Ngoài ra, như những người khác đã đề cập, Delegate cung cấp phương thức "DynamicInvoke" cho phép bạn gọi bất kỳ đại biểu nào.

3

Một điều gọn gàng, bạn có thể làm với delegate từ khóa là tạo ra các đại biểu nội tuyến, mà không cần phải khai báo, ví dụ:

// constructor 
public Form1() 
{ 
    this.Load += delegate(object sender, EventArgs e) 
    { 
     // Form1_Load code goes right here 
    } 
} 
+3

Cú pháp lambda C# 3.0 ít chi tiết hơn nhiều. –

2

Một trong những điều các lớp Delegate có thể được sử dụng cho là kiểm soát nhiều hơn khi gọi xử lý sự kiện. Ví dụ, với xử lý sự kiện bình thường, một ngoại lệ trong bất kỳ trình xử lý sự kiện nào sẽ ngăn chặn bất kỳ trình xử lý sự kiện nào sau này được gọi. Bạn có thể thay đổi hành vi đó bằng cách sử dụng lớp Delegate để gọi thủ công từng trình xử lý sự kiện.

using System; 

namespace DelegateClass 
{ 
    class EventSource 
    { 
     public event EventHandler TheEvent; 

     internal void RaiseEvent1() 
     { 
      EventHandler handler = TheEvent; 
      if (handler != null) 
       handler(this, EventArgs.Empty); 
     } 

     internal void RaiseEvent2() 
     { 
      EventHandler handler = TheEvent; 
      if (handler == null) 
       return; 

      Delegate[] handlers = handler.GetInvocationList(); 
      foreach (Delegate d in handlers) 
      { 
       object[] args = new object[] { this, EventArgs.Empty }; 
       try 
       { 
        d.DynamicInvoke(args); 
       } 
       catch (Exception ex) 
       { 
        while (ex.InnerException != null) 
         ex = ex.InnerException; 

        Console.WriteLine(ex.Message); 
       } 
      } 
     } 
    } 

    class Program 
    { 
     static void Handler1(object sender, EventArgs e) 
     { 
      Console.WriteLine("Handler1"); 
     } 

     static void Handler2(object sender, EventArgs e) 
     { 
      Console.WriteLine("Handler2"); 
      throw new InvalidOperationException(); 
     } 

     static void Handler3(object sender, EventArgs e) 
     { 
      Console.WriteLine("Handler3"); 
     } 

     static void Main(string[] args) 
     { 
      EventSource source = new EventSource(); 
      source.TheEvent += Handler1; 
      source.TheEvent += Handler2; 
      source.TheEvent += Handler3; 

      try 
      { 
       source.RaiseEvent1(); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.Message); 
      } 

      Console.WriteLine("-------------------"); 

      source.RaiseEvent2(); 
     } 
    } 
} 
Các vấn đề liên quan