Tener hijos llame a los eventos públicos de los padres con los datos generados de un evento protegido -- # campo con generics campo con inheritance campo con event-handling camp codereview Relacionados El problema

Having children call parent's public events with data generated from a protected event


5
vote

problema

Español

No sé que mi título describe el código que quiero revisado. Esperemos que el código sea explicativo.

Tengo una clase de padres abstractos con dos hijos. El padre escucha algunas notificaciones de hardware y, cuando el hardware apropiado está conectado / eliminado / frito en mantequilla, etc., plantea un evento a sus hijos que realizan algún procesamiento con los datos del cambio.

Los niños Luego plantean un evento público en el padre con los datos procesados, que es lo que no estoy seguro. Aquí están las clases (eliminadas hacia abajo).

  public abstract class DeviceDetector<TEventArgs> {     public event Action<TEventArgs> DeviceArrived;     public event Action<TEventArgs> DeviceRemoved;     protected void OnDeviceChange(TEventArgs e)     {          if (e.Arrival && DeviceArrived != null)              DeviceArrived(e);          if (!e.Arrival && DeviceRemoved != null)              DeviceRemoved(e);     }      protected event Action<string> DeviceArrival;     protected event Action<string> DeviceRemoval;  }   

Cada uno de los dos niños se define de la siguiente manera:

  public class SomeDescriptiveChildName: DeviceDetector<DeviceChild1EventArgs> {     public SomeDescriptiveChildName()     {         this.DeviceArrival += new Action<string>(HandleProtectedEvent);         this.DeviceRemoval += new Action<string>(HandleProtectedEvent);     }     private void HandleProtectedEvent(string e)     {          //Class names have been changed to protect the innocent.          DeviceChild1EventArgs e = new DeviceChild1EventArgs();           base.OnDeviceChange(e);     } }  public class AnotherDescriptiveChildName: DeviceDetector<DeviceChild2EventArgs> {     public AnotherDescriptiveChildName()     {         this.DeviceArrival += new Action<string>(HandleProtectedEvent);         this.DeviceRemoval += new Action<string>(HandleProtectedEvent);     }     private void HandleProtectedEvent(string e)     {          DeviceChild2EventArgs e = new DeviceChild2EventArgs();           base.OnDeviceChange(e);     } }   

El DeviceChild1EventArgs y DeviceChild2EventArgs son las clases que heredan de EventArgs para representar los datos de cada niño.

Mi pregunta es esta: ¿Existe una mejor manera de representar los datos pasados ​​a los niños a través de DeviceArrival y DeviceRemoval (en este ejemplo, usé cadena, no es un cadena) sin el uso de genéricos, etc ...

Para mí, esto parece algo como una sobremejil, pero es la única forma en que podría pensar en hacer esto.

Original en ingles

I don't know that my title describes the code I want reviewed. Hopefully the code is explanatory.

I have an abstract parent class with two children. The parent listens to some hardware notifications and, when the appropriate hardware is connected/removed/fried in butter etc.., raises an event to its children who perform some processing with the data from the change.

The children then raise a public event on the parent with the processed data, which is what I'm unsure of. Here are the (stripped down) classes.

public abstract class DeviceDetector<TEventArgs> {     public event Action<TEventArgs> DeviceArrived;     public event Action<TEventArgs> DeviceRemoved;     protected void OnDeviceChange(TEventArgs e)     {          if (e.Arrival && DeviceArrived != null)              DeviceArrived(e);          if (!e.Arrival && DeviceRemoved != null)              DeviceRemoved(e);     }      protected event Action<string> DeviceArrival;     protected event Action<string> DeviceRemoval;  } 

Each of the two children is defined as follows:

public class SomeDescriptiveChildName: DeviceDetector<DeviceChild1EventArgs> {     public SomeDescriptiveChildName()     {         this.DeviceArrival += new Action<string>(HandleProtectedEvent);         this.DeviceRemoval += new Action<string>(HandleProtectedEvent);     }     private void HandleProtectedEvent(string e)     {          //Class names have been changed to protect the innocent.          DeviceChild1EventArgs e = new DeviceChild1EventArgs();           base.OnDeviceChange(e);     } }  public class AnotherDescriptiveChildName: DeviceDetector<DeviceChild2EventArgs> {     public AnotherDescriptiveChildName()     {         this.DeviceArrival += new Action<string>(HandleProtectedEvent);         this.DeviceRemoval += new Action<string>(HandleProtectedEvent);     }     private void HandleProtectedEvent(string e)     {          DeviceChild2EventArgs e = new DeviceChild2EventArgs();           base.OnDeviceChange(e);     } } 

The DeviceChild1EventArgs and DeviceChild2EventArgs are classes inheriting from EventArgs to represent the data from each child.

My question is this: Is there a better way to represent the data passed to the children through DeviceArrival and DeviceRemoval (in this example I used string, it's not a string) without the use of generics etc...

To me this seems somewhat like overkill, but it's the only way I could think of doing this.

           
     
     

Lista de respuestas

3
 
vote
vote
La mejor respuesta
 

Los eventos en la clase base no siguen los estándares:

  BookItem& operator=( const BookItem &bookItem );0  

Estaría esperando algo como esto:

  BookItem& operator=( const BookItem &bookItem );1  

Puntos de pareja:

  • Los eventos pueden ser declarados con cualquier tipo de delegado ( 99887776655443322 obras), pero la convención es usar un 998877766555443323 o 99887766555443324 delegado. < / li>
  • Convención para nombramientos de eventos que vienen en pares (recaudados antes y después de que suceda "cosa o tal" "sucede) es prefijar los nombres de los eventos con" ANTES "y" Después ", y usar el tiempo pasado como lo ha hecho. < / li>
  • BookItem& operator=( const BookItem &bookItem );5 debe llamarse BookItem& operator=( const BookItem &bookItem );6 ... pero no está claro por qué el método debe criar a ambos ... Llegado y ... eliminado eventos sin [aparentemente] haciendo nada en el medio.

Una clase base no debe saber, o cuidar, sobre si ha derivado de clases o no. Tienes eso bien, pero una clase derivada que está escuchando eventos planteados en la clase base, no tiene sentido para mí.

No creo que los eventos sean la forma adecuada de lograr lo que está tratando de hacer aquí. Dicho esto, no estoy seguro exactamente qué está tratando de lograr ( El código recortado hace eso ;), pero me aventuraría para sugerirles Métodos plantelados < / em> en lugar de eventos.

en la clase base:

  BookItem& operator=( const BookItem &bookItem );7  

La clase base puede llamar a estos métodos, aunque no se implementan, 99887766555443328 los métodos deben implementarse en las clases derivadas para que el código se compile incluso.

entonces en lugar de esto:

  BookItem& operator=( const BookItem &bookItem );9  

Solo tienes eso:

  ~BookItem(){}0  

y las clases derivadas tienen las implementaciones:

  ~BookItem(){}1  
 

The events in the base class don't follow the standards:

public event Action<TEventArgs> DeviceArrived; public event Action<TEventArgs> DeviceRemoved;  protected event Action<string> DeviceArrival; protected event Action<string> DeviceRemoval; 

I'd be expecting something like this:

public event EventHandler<TEventArgs> AfterDeviceArrived; public event EventHandler<TEventArgs> AfterDeviceRemoved;  protected event EventHandler<SomeEventArgsClass> BeforeDeviceArrived; protected event EventHandler<SomeEventArgsClass> BeforeDeviceRemoved; 

Couple points:

  • Events can be declared with any delegate type (Action<T> works), but the convention is to use an EventHandler or EventHandler<TEventArgs> delegate.
  • Convention for naming events that come in pairs (raised before and after such or such "thing" happens) is to prefix the event names with "Before" and "After", and use past tense as you've done.
  • OnDeviceChange should be called OnDeviceChanged.. but it's not clear why the method needs to raise both ...Arrived and ...Removed events without [apparently] doing anything in-between.

A base class shouldn't know, or care, about whether it has derived classes or not. You've got that right, but a derived class that's listening for events raised in the base class, doesn't make sense to me.

I don't think events are the appropriate way to accomplish what you're trying to do here. That said I'm not sure exactly what you're trying to accomplish (trimmed code does that ;) - but I'd venture to suggest templated methods instead of events.

In the base class:

// todo: remove notion of "event args" protected abstract void OnDeviceArrived(TEventArgs e); protected abstract void OnDeviceRemoved(TEventArgs e); 

The base class can call these methods even though they're not implemented - abstract methods must be implemented in the derived classes for the code to even compile.

So instead of this:

     if (e.Arrival && DeviceArrived != null)          DeviceArrived(e);      if (!e.Arrival && DeviceRemoved != null)          DeviceRemoved(e); 

You just have that:

    if (e.Arrival)      {         OnDeviceArrived(e);     }     else     {         OnDeviceRemoved(e);     } 

And the derived classes have the implementations:

protected override void OnDeviceArrived(TEventArgs e) {     // ... }  protected override void OnDeviceRemoved(TEventArgs e) {     // ... } 
 
 

Relacionados problema

1  Manipulador de eventos repetitivos para un control de interfaz de usuario de la UI  ( Repetitive event handler for a toggling ui control ) 
Siento que este tipo de código podría haber sido escrito más elegante, especialmente con las enormes afirmaciones de IF / ODS. ¿Alguien puede ayudarme a rompe...

8  Grabadora para eventos de teclado y ratón  ( Recorder for keyboard and mouse events ) 
Estoy construyendo una grabadora de eventos. Hasta ahora, el código se ve limpio, pero siento que me falta algo que puede hacer que este código sea aún mejor....

5  Mouselistener Lag en el juego de azulejos de piano  ( Mouselistener lag in piano tiles game ) 
Estaba intentando escribir mi propia versión simple de la aplicación de juegos de piano azulejos en Java, así como un ejercicio divertido. gamelogic.java ...

7  Control de finanzas con desarrollo web  ( Controlling finances with web development ) 
Propósito Primero, déjame explicar el título: Anteriormente, había manejado mis finanzas como una compañía antigua, y funcionaba maravillas por tomar decisi...

7  Incluso manejador para la vista previa de entrada de texto  ( Even handler for text input preview ) 
En una aplicación WPF, tengo el siguiente controlador de eventos para (x1,y1),(x2,y2)8 en (x1,y1),(x2,y2)9 Control. El propósito principal de este Código ...

6  ¿Está mi delegado definió la forma correcta y necesita transformarse en una mariposa bonita?  ( Is my delegate defined the right way and does it need to transform to a pretty e ) 
He leído tantos Historias de tiempo de cama e inserciones de cómo < fuertes> delegados trabajo y por qué eventos deben ser reemplazados por los delegado...

4  Inicializando eventos en clase  ( Initializing events on class ) 
Escribí una clase simple que sustituye todas las entradas de archivos en un HTML para una plantilla más compleja y configura algunas acciones en él. El código...

6  Vuelos divectores de división vue.js  ( Resizable split divs vue js ) 
Acabo de empezar a desarrollar la aplicación web (VUE.JS) para mi empresa por alrededor de 1-2 meses. Por lo tanto, mi conocimiento y experiencia en HTML, CSS...

13  Configuración del botón de radio, haga clic en ActionListeners  ( Setting up radio button click actionlisteners ) 
En lugar de escribir cuatro llamadas de método, me opté por iterar sobre una matriz, pero me pregunto si esta era la mejor manera de hacerlo. ..escribí a Ithe...

6  Sistema de eventos personalizado en C #  ( Custom event system in c ) 
Actualmente estoy escribiendo un juego y quiero codificar todo lo que sucede (GameObject se ha movido, HP cambió, fue creado / destruido, se ha creado / perdi...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos