Неправильное выполнение методов класса для события? - PullRequest
3 голосов
/ 17 ноября 2011
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();
    } 
}

Теперь, что происходит, после того, как я прохожу цикл, в котором вызываются оба метода StartB (называемый первым) и StartC (называемый вторым), когда someevent запущен, код пытается выполнить метод в Class B ( и более поздних классах C, я надеюсь. Я не смог туда попасть, поскольку он выдает ошибки при вызове метода в Класс B ), вместо которого я хочу, чтобы он вызывал только метод в Класс C .

Я думаю, что, поскольку событие подписано в конструкторе, методы класса B по-прежнему запускаются, поскольку оно подписано изначально при вызове StartB.

Вопрос:
Я хочу, чтобы выполнялись только методы класса, для которого был создан экземпляр.

Например: если StartB и StartC вызываются по порядку, когда someevent запускается, методы в Class C должны только быть казненным. Та же и наоборот. Как это сделать?

Я знаю, что делаю что-то ужасно неправильно. Любая помощь очень ценится.

Ответы [ 2 ]

3 голосов
/ 17 ноября 2011

Вы не отменили подписку на событие из своего первого экземпляра, поэтому оно будет вызвано. Если вы не хотите, чтобы он вызывался, вам нужно отписаться. Вы могли бы сделать что-то подобное

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;
}

но кажется довольно хакерским. Возможно, вам лучше реализовать метод (например, IDisposable) для очистки вашего последнего экземпляра перед созданием нового.

1 голос
/ 17 ноября 2011

Если я вас правильно понимаю, вы говорите, что методы на B вызываются после вызова startC, и вы не хотите, чтобы это произошло?

Я предполагаю, что ваша проблема в том, что someotherclass является статическим классом, или экземпляр каким-то образом распределяется между всеми созданными B и C - в этом случае вам нужно отменить регистрацию старого обработчика событий в someotherclass.someevent при создании новый класс. Если вы не отмените регистрацию обработчика, тогда объект someotherclass будет иметь ссылку на зарегистрированный в нем объект B или C, поэтому, даже если вы перезаписываете ссылку в главном классе, объект по-прежнему сохраняется живым посредством ссылки в событие и все еще вызывается, когда событие инициируется.

...