Reenvío de eventos en C#


Estoy usando una clase que reenvía eventos en C#. Me preguntaba si hay una manera de hacer eso requiere menos sobrecarga de código.

Aquí hay un ejemplo de lo que tengo hasta ahora.

class A
{
   public event EventType EventA;
}

class B
{
   A m_A = new A();
   public event EventType EventB;

   public B()
   {
      m_A.EventA += OnEventA;
   }

   public void OnEventA()
   {
      if( EventB )
      {
         EventB();
      }
   }
}

La clase A eleva el evento original. La clase B lo reenvía como EventB (que es esencialmente el mismo evento). La clase A está oculta de otros módulos, por lo que no pueden suscribirse directamente a EventA.

Lo que estoy tratando de hacer es reducir la sobrecarga de código en clase B para reenviar el evento, ya que normalmente no hay un manejo real de los eventos en la clase B. También tendré varios eventos diferentes, por lo que requeriría escribir muchos métodos OnEvent() en la clase B que solo sirven para reenviar los eventos.

¿Es posible vincular automáticamente EventA a EventB de alguna manera, así que tendría algo como esto:

class B
{
   A m_A = new A();
   public event EventType EventB;

   public B()
   {
      m_A.EventA += EventB; // EventA automatically raises EventB.
   }
}

Estoy usando un compilador de C# 2.0 por cierto.

Author: user3891, 2009-06-30

2 answers

Absolutamente:

class B
{
    private A m_a = new A();

    public event EventType EventB
    {
        add { m_a.EventA += value; }
        remove { m_a.EventA -= value; }
    }
}

En otras palabras, el código de suscripción/cancelación de suscripción de EventB simplemente pasa las solicitudes de suscripción/cancelación de suscripción a EventA.

Tenga en cuenta que esto no le permite elevar el evento solo para los suscriptores que se suscribieron a EventB, sin embargo. Es como pasar la dirección de alguien directamente a una empresa de marketing masivo, mientras que su forma original es más como suscribirse a la empresa de marketing masivo usted mismo, y permitir que la gente le pida que envíe copias de los correos a ellos.

 72
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-30 19:01:19

IMO, su código original es (más o menos) correcto. En particular, le permite proporcionar la sender correcta (que debería ser la instancia B para las personas que piensan que se están suscribiendo a un evento en B).

Hay algunos trucos para reducir los gastos generales en tiempo de ejecución si el evento no está suscrito, pero esto agrega más código:

class B {
   A m_A = new A();
   private EventType eventB;
   public event EventType EventB {
       add { // only subscribe when we have a subscriber ourselves
           bool first = eventB == null;
           eventB += value;
           if(first && eventB != null) m_A.EventA += OnEventB;
       }
       remove { // unsubscribe if we have no more subscribers
           eventB -= value;
           if(eventB == null) m_A.EventA -= OnEventB;
       }
   }

   protected void OnEventB(object sender, EventArgsType args) {
      eventB?.Invoke(this, args); // note "this", not "sender"

   }
}
 10
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-16 12:26:59