2010-02-17 48 views
8

Giả sử tôi có giao diện "Bộ xử lý" hiển thị sự kiện - OnProcess. Thông thường người triển khai thực hiện quá trình xử lý. Vì vậy, tôi có thể đăng ký một cách an toàn sự kiện này và chắc chắn rằng nó sẽ bị sa thải. Nhưng một bộ xử lý không xử lý - do đó tôi muốn ngăn người đăng ký thuê lại trên đó. Tôi có thể làm điều đó? Nói cách khác trong các mã dưới đây tôi muốn dòng cuối cùng để ném một ngoại lệ:Sự kiện .NET - chặn người đăng ký đăng ký một sự kiện

var emptyProcessor = new EmptyProcessor(); 
emptyProcessor.OnProcess += event_handler; // This line should throw an exception. 
+0

Hãy tưởng tượng bạn là người được chỉ định để tìm hiểu lý do mã bị treo. Bạn có tìm lỗi ở dòng này không? –

Trả lời

8
class EmptyProcessor : IProcessor { 

    [Obsolete("EmptyProcessor.OnProcess should not be directly accessed", true)] 
    public event EventHandler OnProcess { 
     add { throw new NotImplementedException(" :("); } 
     remove { } 
    } 
} 

Trong tình huống này, các tham số true trên Obsolete gây ra một ngoại lệ thời gian biên dịch. vậy:

EmptyProcessor processor1 = new EmptyProcessor(); 
IProcessor processor2 = new EmptyProcessor(); 

processor1.OnProcess += handler; // <-- compile-time error 
processor2.OnProcess += handler; // <-- run-time error 
+0

Cảm ơn bạn rất nhiều – Moshe

+0

Wow ... Tôi thậm chí không biết bạn có thể làm điều đó. Tôi vừa viết một ứng dụng mẫu nhanh để kiểm tra nó, và ai biết ... nó hoạt động. Rất thú vị. – Nick

+0

+1, mặc dù tôi không chắc chắn thông báo ngoại lệ này sẽ rất hữu ích;) –

0

Bạn có thể thực hiện nó với tùy chỉnh add/remove phương pháp nhưng tôi tin rằng đây là một thực tế xấu.

Hãy xem, bạn có giao diện , hợp đồng sẽ được các lớp khác nhau triển khai.
OnProcess là một phần của hợp đồng này và không phải là đặc biệt theo bất kỳ cách nào.

Một thường sử dụng giao diện khi cô muốn hoạt động với các lớp khác nhau trong cùng một tập hợp hoạt động. Giao diện cho phép bạn mã như sau:

IProcessor proc = GetProcessorAnyhow(); 
proc.DoSomething(); 

mà không biết loại bê tông ở dạng biên dịch.

Tuy nhiên, với cách tiếp cận của bạn,

IProcessor proc = GetProcessorAnyhow(); 
proc.OnProcess += (sender, e) => { }; 

có thể thất bại mà không cần bất cứ lý do rõ ràng, mặc dù nó trông giống như mã hoàn toàn hợp pháp.
Always make sure that wrong code looks wrong.

Bạn có thể đã thực hiện một trong những sai lầm thiết kế sau:

  • Đặt OnProcess trong IProcessor trong khi nó có thể không mỗi xử lý của hợp đồng;
  • Made EmptyProcessor triển khai IProcessor, trong khi thực tế nó không thể đáp ứng hợp đồng.
Các vấn đề liên quan