1

I have an interface defining an event:

interface IEXampleinterface 
{
   event MyEventHandler MyEvent;
}

In my GUI class I am calling a "processor" class which is again calling a "parser" class which implements the interface:

class GUI
{
   public DoSomething()
   {
      Processor processor = new Processor();
      processor.MyEvent += new MyEventHandler(processor_myevent);
      processor.DoSomething();
   }
   public processor_myevent(object sender, EventArgs e)
   {
      ...
   }
}

Processor class:

class processor
{
   IExampleInterface parser;
   event MyEventHandler MyEvent;

   public void DoSomething()
   {
      parser = new Parser();
      parser.MyEvent += new MyEventHandler(parser_myevent);
      parser.DoStuff();
   }
   public void parser_myevent(object sender, EventArgs e)
   {
      if(MyEvent != null)
      {
         MyEvent(sender, e)
      }
   }
}

Parser class:

class Parser : IExampleinterface
{
   event MyEventHandler MyEvent;

   public void DoStuff()
   {
      MyEvent(this, new EventArgs());
   }
}

As you can see, the "Processor" class just takes the event from "Parser" and forwards it to the GUI. This is totally working, but I was asking if there is a more elegant way of doing this kind of event forwarding.

ProgrammingDude
  • 597
  • 1
  • 5
  • 25
  • 2
    FWIW (and unrelated to your Q), this: `if(MyEvent != null)` should be more like `var local = MyEvent; if (local != null) { local(sender...` - just in case the last event handler is removed between the `if` and actually calling it. [More info here](http://stackoverflow.com/questions/786383/c-sharp-events-and-thread-safety). – James Thorpe Jan 08 '16 at 15:07
  • In short: what James proposed is thread-safe. Yours isn't. – Patrick Hofman Jan 08 '16 at 15:08
  • It seems like you are passing the event handler from Parse to Processor to GUI. The "to processor" part is not needed unless you actually need it. – Camilo Terevinto Jan 08 '16 at 15:08
  • @cFrozenDeath I do need the processor, because in my program it is supposed to deploy multiple parsers for different purposes. – Erik Moldtmann Jan 08 '16 at 19:10

2 Answers2

2

Instead of creating a new event and pass events through, you could also point directly to that event:

public event MyEventHandler MyEvent
{
    add
    {
        parser.MyEvent += value;
    }
    remove
    {
        parser.MyEvent -= value;
    }
}

I am not sure if this is the prettiest thing to do, maybe you are better off with a better design. However, this will do the job until I have figured out a better way ;) .

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • I already tried that and unfortunately it throws a NullReference because parser is not instantiated at the time when processor is instantiated – Erik Moldtmann Jan 08 '16 at 19:12
2

First of all, doing MyEvent(sender, e) is considered "bad", the sender parameter should always be this so you know which event publisher raised the event. GUI has no reference to parser so it can't do any of the normal comparisons to tell which parser raised the event and this may break some UI frameworks that rely on the "standard" event pattern.

That being said, you can change how events are subscribed and unsubscribed to forward the subscription

class processor
{
   IExampleInterface parser;
   event MyEventHandler MyEvent
   {
      add { parser.MyEvent += value; }
      remove { parser.MyEvent -= value; }
   }

This gives the same behavior as MyEvent(sender, e)

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431