Search code examples
c#eventsinheritancecustom-event

Wrong Derived Class Methods Execution on Event?


public Class A
{

   public A()
   {
     someotherclass.someevent += new EventHandler(HandleEvent);
   }

   private void HandleEvent(object sender,CustomEventArgs e) 
   {
      if(e.Name == "Type1")
           Method1();
      else if(e.Name == "Type2")
           Method2();
   }

   protected virtual void Method1(){}
   protected virtual void Method2(){}
}

public class B: A
{
   public B()
   { /*Something*/}

   protected override void Method1(){/*some logic*/}
   protected override void Method2(){/*some other logic*/}
}

public class C: A
{
   public C()
   { /*Something*/}

   protected override void Method1(){/*some logic*/}
   protected override void Method2(){/*some other logic*/}
}

public class Main
{
    private A;

    public Main(){/*Something*/}

    private void StartB()
    {
       A = new B();
    } 

    private void StartC()
    {
       A = new C();
    } 
}

Now, what happens is, after I go through a cycle in which both the methods StartB(called first) and StartC(called second) are called, when the someevent is triggered, the code tries to execute the Method in Class B(and later Class C, I hope. I could not get there since it errors out when it calls method in Class B), instead which I want it to call only the method in Class C.

I think that, since the event is subscribed at constructor, Class B methods are still getting fired since it is subscribed initially on the call of StartB.

Question:
I want only the methods of the class that is instantiated the latest should be executed.

For Example: if StartB and StartC are called in order, when someevent is triggered the Methods in Class C should only get executed. Same Vice-Versa. How to do that?

I know am doing something terribly wrong. Any help is much appreciated.


Solution

  • You aren't unsubscribing from the event from your first instance so it will be called. If you don't want it to be called you need to unsubscribe. You could do something like this

    class A
    {
    
    private static EventHandler lastHandler;
    
    public A()
    {
        //warning, not thread safe
        if(lastHandler != null)
        {
            someotherclass.someevent -= lastHandler;
        }
        lastHandler = new EventHandler(HandleEvent);
        someotherclass.someevent += lastHandler;
    }
    

    but it seems pretty hacky. You are probably better off implementing a method (e.g. IDisposable) to clean up your last instance before a creating a new one.