2010-02-17 3 views
8

Предположим, у меня есть интерфейс «Процессор», отображающий событие - OnProcess. Обычно разработчики выполняют обработку. Таким образом, я могу спокойно подписаться на это событие и быть уверенным, что он будет запущен. Но один процессор не обрабатывает, поэтому я хочу, чтобы подписчики не подписались на него. Я могу это сделать? Другими словами, в приведенном ниже коде я хочу, чтобы последняя строка бросить исключение:События .NET - блокирование подписчиков от подписки на событие

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

Представьте, что вы были человеком, которому было поручено выяснить причину сбоя кода. Будете ли вы искать ошибку в этой строке? –

ответ

8
class EmptyProcessor : IProcessor { 

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

В этой ситуации параметр на Устаревшие true вызывает время компиляции исключение. так:

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

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

Огромное вам спасибо – Moshe

+0

Wow ... Я даже не знал, что вы можете это сделать. Я просто написал приложение для быстрого образца, чтобы проверить его, и кто знал ... это сработало. Очень интересно. – Nick

+0

+1, хотя я не уверен, что это сообщение об исключении было бы очень полезно;) –

0

Вы можете реализовать его с обычаем add/remove методы, но я считаю, что это плохая практика.

Посмотрите, у вас есть интерфейс , а контракт быть реализованы различными классами.
OnProcess является частью этого договора и не является каким-либо особым.

Обычно используется интерфейс, когда она хочет работать с разными классами при одном и том же множестве операций. Интерфейсы позволяют вам вводить код следующим образом:

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

, не зная конкретного типа при компиляции.

Однако, с вашим подходом,

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

может выйти из строя без какой-либо видимой причины, хотя это выглядит абсолютно законным кодом.
Always make sure that wrong code looks wrong.

Вы, возможно, сделали один из следующих конструктивных ошибок:

  • Поместите OnProcess в IProcessor тогда не может быть каждый процессора контракт;
  • Изготовлен EmptyProcessor орудие IProcessor, тогда как фактически не может удовлетворить контракт.
Смежные вопросы