2013-03-03 23 views
6

Tôi biết Sự kiện luôn được liên kết với Đại biểu. Nhưng, tôi thiếu một số sử dụng cốt lõi của Sự kiện và cố gắng hiểu điều đó.Tại sao lại sử dụng sự kiện cho những gì tôi có thể làm với Đại biểu?

Tôi đã tạo một chương trình Sự kiện đơn giản như dưới đây và chương trình hoạt động hoàn toàn tốt.

namespace CompleteRef3._0 
{ 
delegate void someEventDelegate(); 

class EventTester 
{ 
    public event someEventDelegate someEvent; 

    public void doEvent() 
    { 
     if (someEvent != null) someEvent(); 
    } 

} 

class Program 
{ 
    static void EventHandler1() 
    { 
     Console.WriteLine("Event handler 1 called.."); 
    } 

    static void EventHandler2() 
    { 
     Console.WriteLine("Event handler 2 called.."); 
    } 
    static void EventHandler3() 
    { 
     Console.WriteLine("Event handler 3 called.."); 
    } 


    static void Main(string[] args) 
    { 
     EventTester evt = new EventTester(); 
     evt.someEvent += EventHandler1; 
     evt.someEvent += EventHandler2; 
     evt.someEvent += EventHandler3; 
     evt.doEvent(); 
     Console.ReadKey(); 

    } 
} 
} 

Tôi đã thay thế khai báo sự kiện với đại biểu. Đó là tôi đã thay thế dòng sự kiện công khai someEventDelegate someEvent; với someEventDelegate someEvent; về chương trình trên và tôi vẫn nhận được kết quả tương tự. Bây giờ, tôi đã nhầm lẫn lý do tại sao chúng ta cần phải sử dụng sự kiện, nếu nó chỉ có thể đạt được bởi đại biểu. Việc sử dụng thực sự của sự kiện là gì?

Chương trình sửa đổi mà không cần sự kiện như sau -

namespace CompleteRef3._0 
{ 
delegate void someEventDelegate(); 

class EventTester 
{ 
    someEventDelegate someEvent; 

    public void doEvent() 
    { 
     if (someEvent != null) someEvent(); 
    } 

} 

class Program 
{ 
    static void EventHandler1() 
    { 
     Console.WriteLine("Event handler 1 called.."); 
    } 

    static void EventHandler2() 
    { 
     Console.WriteLine("Event handler 2 called.."); 
    } 
    static void EventHandler3() 
    { 
     Console.WriteLine("Event handler 3 called.."); 
    } 


    static void Main(string[] args) 
    { 
     EventTester evt = new EventTester(); 
     evt.someEvent += EventHandler1; 
     evt.someEvent += EventHandler2; 
     evt.someEvent += EventHandler3; 
     evt.doEvent(); 
     Console.ReadKey(); 

    } 
} 
} 
+0

Tóm lại, phơi bày ngắt tham gia công khai ** đóng gói **. – Timeless

Trả lời

4

Chắc chắn, bạn có thể sử dụng các đại biểu vì đằng sau hậu trường một sự kiện là một cấu trúc bọc lấy một đại biểu.

Nhưng lý do sử dụng sự kiện thay vì người được ủy quyền giống như sử dụng thuộc tính thay cho trường - gói dữ liệu. Thực hành không tốt để phơi bày các trường (bất kể chúng là gì - các trường nguyên thủy hoặc các đại biểu) trực tiếp.

Nhân tiện, bạn đã bỏ lỡ một từ khóa public trước trường đại biểu của mình để có thể thực hiện trong đoạn thứ hai.

Một "nhân tiện" khác với đoạn mã thứ hai: đối với các đại biểu, bạn nên sử dụng Delegate.Combine thay vì "+ =".

+0

oh ya .. sai lầm của tôi Tôi đã bỏ lỡ từ khóa 'public' .. cảm ơn vì đã đánh bắt nó cho tôi. Tôi sẽ chỉnh sửa nó .. Kiến thức tốt cho tôi để sử dụng 'Delegate.Combine'. Tôi không biết điều đó trước đây! ... Câu trả lời của bạn là tốt, chính xác những gì tôi nghĩ - *** đóng gói dữ liệu ***. –

+3

Câu trả lời hay trừ dòng cuối cùng. ** Tại sao chúng ta không nên sử dụng '+' và '+ =' và như vậy với các đại biểu? ** Họ đã được đưa vào ngôn ngữ để làm cho mọi thứ đẹp. Điều quan trọng là phải hiểu sự khác biệt giữa '+ =' với các sự kiện (một cú pháp để gọi 'access' event accessor), và' + = 'với các biến (ở đây' x + = y' giống như 'x = x + y' trong đó '+' có thể được kết hợp đại biểu, nối chuỗi, bổ sung số học của một số loại hoặc các tình trạng quá tải khác). Một vấn đề với 'Delegate.Combine' là các kiểu không được kiểm tra ở tất cả các thời gian biên dịch. Với '+' các kiểu biên dịch được kiểm tra. –

7

Mục đích chính của sự kiện là để ngăn chặn các thuê bao từ can thiệp với nhau. Nếu bạn không sử dụng sự kiện, bạn có thể:

Thay thế người đăng ký khác bằng cách chỉ định lại đại biểu (thay vì sử dụng toán tử + =), Xóa tất cả người đăng ký (bằng cách đặt đại biểu thành không), Phát sóng tới người đăng ký khác bằng cách gọi đại biểu.

Nguồn: C# in a Nutshell

+3

+1. Bài tập 'someEvent = new someEventDelegate (EventHandler2)' là vấn đề bạn có với việc sử dụng trực tiếp các ủy nhiệm. Một liên kết khác [Học C# 3.0: Làm chủ các nguyên tắc cơ bản của C# 3.0 - Đại biểu và Sự kiện] (http://msdn.microsoft.com/en-us/library/orm-9780596521066-01-17.aspx) - chương đặc biệt này là avialble trên MSDN và đi vào chi tiết về chủ đề này. –

+0

cảm ơn bạn đã tham khảo .. –

5

Hãy tưởng tượng bạn có 3 người đăng ký quan tâm đến someEvent của bạn.Họ đã đăng ký thậm chí như thế này:

khách hàng 1

EventTester evt = new EventTester(); 
evt.someEvent += Client1Handler1; 
evt.someEvent += Cleint1Handler2; 

Khách hàng 2

EventTester evt = new EventTester(); 
evt.someEvent += Client2Handler1; 
evt.someEvent += Client2Handler2; 

Khách hàng 3

EventTester evt = new EventTester(); 
evt.someEvent += Client2Handler1; 
evt.someEvent += Client2Handler2; 

Bây giờ tưởng tượng khách hàng khác thực hiện điều này:

EventTester = null; 

khách hàng 1, 2, và 3 sẽ không được nhận bất kỳ sự kiện bởi vì bạn có dòng mã này:

if (someEvent != null) someEvent(); 

Không có gì sai với dòng trên của mã là, nhưng có vấn đề với việc sử dụng các đại biểu .

Các vấn đề khác như Alexei chỉ ra là:

someEvent = new someEventDelegate(EventHandler2) 

Nếu bạn có một event và một trong những khách hàng cố gắng trên, họ sẽ không được phép và nhận được một lỗi biên dịch, như thế này:

enter image description here

+0

Cảm ơn bạn. Bạn đã giải thích rất rõ việc sử dụng Sự kiện. :) –

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