2010-02-17 20 views
6

Tôi đã chỉ duyệt và đã xem qua câu hỏi này:xử lý tổ chức sự kiện hội nghị phương pháp nâng

Action vs delegate event

The answer from nobug bao gồm mã này:

protected virtual void OnLeave(EmployeeEventArgs e) { 
    var handler = Leave; 
    if (handler != null) 
    handler(this, e); 
} 

Resharper cũng tạo ra mã tương tự như khi sử dụng "tạo nâng cao phương pháp "sửa lỗi nhanh.

Câu hỏi của tôi là, tại sao là dòng này cần thiết ?:

var handler = Leave; 

Tại sao nó tốt hơn so với văn bản này ?:

protected virtual void OnLeave(EmployeeEventArgs e) { 
    if (Leave != null) 
    Leave(this, e); 
} 

Trả lời

12

Đó là tốt hơn bởi vì có một khả năng nhỏ mà Leave trở nên rỗng sau khi kiểm tra null, nhưng trước khi gọi (điều này sẽ làm cho mã của bạn ném một số NullReferenceException). Vì loại đại biểu là bất biến, nếu bạn lần đầu tiên gán nó cho một biến khả năng này biến mất; bản sao cục bộ của bạn sẽ không bị ảnh hưởng bởi bất kỳ thay đổi nào đối với Leave sau khi chuyển nhượng.

Lưu ý rằng cách tiếp cận này cũng tạo ra sự cố ngược lại; nó có nghĩa là có một khả năng (nhỏ nhưng tồn tại) mà một trình xử lý sự kiện được gọi sau khi nó đã được tách ra khỏi sự kiện. Kịch bản này tất nhiên nên được xử lý một cách duyên dáng.

5

Trong ứng dụng đa luồng, bạn có thể nhận ngoại lệ tham chiếu null nếu người gọi hủy đăng ký khỏi sự kiện. Việc gán cho một biến cục bộ bảo vệ chống lại điều này.

Tỷ lệ cược là bạn sẽ không bao giờ thấy điều này (cho đến khi nó làm bạn đau nhất). Dưới đây là một cách để nhìn vào nó cho thấy các vấn đề ...

protected virtual void OnLeave(EmployeeEventArgs e) { 
    if (Leave != null) //subscriber is registered to the event 
    { 
    //Subscriber unregisters from event.... 
    Leave(this, e); //NullReferenceException! 
    } 
} 
+0

Yup. Bắt xử lý sự kiện được gọi sau khi hủy đăng ký nó là một cuộc đua không thể sửa chữa. NRE dễ dàng sửa chữa được. –

1

Dưới đây là một lời giải thích tuyệt vời của Eric Lippert:

Events and races

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