2010-02-17 16 views
8

Digamos que tengo una interfaz "Procesador" que expone un evento - OnProcess. Usualmente los implementadores hacen el procesamiento. Por lo tanto, puedo suscribirme de forma segura en este evento y asegurarme de que se dispare. Pero un procesador no procesa, por lo que quiero evitar que los suscriptores se subscriban en él. ¿Puedo hacer eso? En otras palabras el código de abajo Quiero que la última línea para lanzar una excepción:. Eventos NET. Bloquea que los suscriptores se suscriban a un evento

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

Imagina que fuiste la persona asignada para descubrir por qué el código se bloquea. ¿Buscarías error en esta línea? –

Respuesta

8
class EmptyProcessor : IProcessor { 

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

En esta situación, el parámetro true en obsoleto provoca una excepción en tiempo de compilación. por lo que:

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

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

Muchas gracias – Moshe

+0

Wow ... Ni siquiera sabía que podrías hacer eso. Acabo de escribir una aplicación de muestra rápida para probarla, y quién sabe ... funcionó. Muy interesante. – Nick

+0

+1, aunque no estoy seguro de que este mensaje de excepción sea muy útil;) –

0

Puede ponerlo en práctica con la costumbre add/remove métodos, pero creo que esto es una mala práctica.

Look, que tiene una interfaz , un contrato a desarrollar por diferentes clases.
OnProcess es parte de este contrato y no es especial de ninguna manera.

Uno generalmente usa interfaces cuando quiere trabajar con diferentes clases bajo el mismo conjunto de operaciones. Las interfaces le permiten codificar de esta manera:

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

sin conocer el tipo de hormigón en el tipo de compilación.

Sin embargo, con su enfoque,

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

pueden fallar sin ninguna razón aparente, aunque parece absolutamente legítimo código.
Always make sure that wrong code looks wrong.

Usted puede haber hecho uno de los siguientes errores de diseño:

  • Ponga OnProcess en IProcessor mientras que puede que no sea cada procesador del contrato;
  • Hecho EmptyProcessor implementar IProcessor, mientras que en realidad no puede cumplir el contrato.
Cuestiones relacionadas