2010-02-17 10 views
8

Angenommen, ich habe ein "Processor" -Interface, das ein Ereignis ausgibt - OnProcess. In der Regel erledigen die Implementierer die Verarbeitung. So kann ich sicher auf diese Veranstaltung abonnieren und sicher sein, dass es gefeuert wird. Aber ein Prozessor verarbeitet keine Daten - daher möchte ich verhindern, dass Abonnenten darauf subscriben. Kann ich das machen? Mit anderen Worten: in dem folgenden Code mag ich die letzte Zeile eine Ausnahme werfen:.NET-Ereignisse - Blockieren von Abonnenten beim Abonnieren eines Ereignisses

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

Stellen Sie sich vor Sie waren die Person zugewiesen, um herauszufinden, warum Code abstürzt. Würdest du nach Fehlern in dieser Zeile suchen? –

Antwort

8
class EmptyProcessor : IProcessor { 

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

In dieser Situation ist die true Parameter auf Veraltet verursachen eine Kompilierung-Ausnahme. so:

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

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

Vielen Dank – Moshe

+0

Wow ... Ich wusste nicht einmal, dass du das kannst. Ich habe gerade eine schnelle Beispielanwendung geschrieben, um es zu testen, und wer weiß ... es hat funktioniert. Sehr interessant. – Nick

+0

+1, obwohl ich nicht sicher bin, dass diese Ausnahmemeldung sehr hilfreich wäre;) –

0

Sie können es mit benutzerdefinierten add/remove Methoden implementieren, aber ich glaube, dass dies eine schlechte Praxis ist.

Schauen Sie, haben Sie eine Schnittstelle, einen Vertrag von verschiedenen Klassen implementiert werden.
OnProcess ist Teil dieses Vertrages und ist in keiner Weise besonders.

Man verwendet normalerweise Schnittstellen, wenn sie mit verschiedenen Klassen unter der gleichen Reihe von Operationen arbeiten möchte. Schnittstellen ermöglichen Ihnen, wie folgt zu codieren:

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

ohne konkreten Typ beim Kompilieren zu kennen.

jedoch mit Ihrem Ansatz,

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

kann ohne ersichtlichen Grund fehlschlagen, obwohl es wie absolut legitim Code aussieht.
Always make sure that wrong code looks wrong.

Sie haben möglicherweise eine der folgenden Design-Fehler gemacht:

  • Put OnProcess in IProcessor während es nicht jeder Prozessor Vertrag sein kann;
  • Hergestellt EmptyProcessor implementieren IProcessor, während eigentlich es den Vertrag nicht erfüllen kann.
Verwandte Themen