События .NET - блокировка подписчиков на подписку на событие - PullRequest
8 голосов
/ 17 февраля 2010

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

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

Ответы [ 2 ]

8 голосов
/ 17 февраля 2010
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 голосов
/ 05 марта 2011

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

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

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

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

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

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

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

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

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

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