【问题标题】:Wrong Derived Class Methods Execution on Event?对事件执行错误的派生类方法?
【发布时间】:2011-11-17 08:38:59
【问题描述】:
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 被触发,代码尝试执行 B 类 中的方法(希望以后还有 C 类。我无法到达那里,因为它在它调用 B 类中的方法),而不是我希望它只调用 C 类中的方法。

我认为,由于事件是在构造函数中订阅的,因此 B 类方法仍然会被触发,因为它最初是在 StartB 调用时订阅的。

问题:
我只想执行最新实例化的类的方法。

例如:如果依次调用StartBStartC,当someevent被触发时Class C中的方法 strong> 应该只被执行。反之亦然。该怎么做?

我知道我做错了什么。非常感谢任何帮助。

【问题讨论】:

  • 有什么问题?你说的是对的,但你没有问任何问题

标签: c# events inheritance custom-event


【解决方案1】:

您不会从第一个实例中取消订阅该事件,因此它将被调用。如果您不希望它被调用,则需要取消订阅。你可以做这样的事情

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)来清理您的最后一个实例。

【讨论】:

  • 谢谢亚尔。在创建新实例之前,我实现了 IDisposable 接口并取消订阅 Dispose 方法中的事件。成功了!
【解决方案2】:

如果我理解正确,您是说 B 上的方法是在调用 startC 之后调用的,而您不希望这种情况发生?

我猜你的问题是 someotherclass 是一个静态类,或者一个实例在所有创建的 B 和 C 之间以某种方式共享 - 在这种情况下,你需要在创建时从 someotherclass.someevent 注销旧的事件处理程序新班级。如果您不取消注册处理程序,那么 someotherclass 对象将具有对向其注册的 B 或 C 对象的引用,因此即使您覆盖主类中的引用,该对象仍然通过引用中的引用保持活动状态事件并且在事件触发时仍然被调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多