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的调用下订阅的。
问题:
我只想要执行最新实例化的类的方法。
例如:如果按顺序调用 StartB 和 StartC ,则触发 someevent 时 C类中的方法应该只执行。同样的副Versa。怎么做?
我知道我做的事情非常糟糕。非常感谢任何帮助。
答案 0 :(得分:3)
您不会取消订阅第一个实例中的事件,因此会调用它。如果您不希望它被调用,您需要取消订阅。你可以做这样的事情
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 :(得分:1)
如果我理解正确你说你在调用startC之后调用B上的方法并且你不希望这种情况发生吗?
我猜你的问题是someotherclass是一个静态类,或者某个实例以某种方式在所有创建的B和C之间共享 - 在这种情况下,你需要在创建时从someotherclass.someevent取消注册旧的事件处理程序新班级。如果你没有取消注册处理程序,那么someotherclass对象将具有对其注册的B或C对象的引用,因此即使你覆盖了主类中的引用,对象仍然通过引用保持活动状态。事件被触发时仍然被调用。