子/父事件引发
本文关键字:事件 | 更新日期: 2023-09-27 18:16:48
我有一个父抽象类和几个子类。最后,我希望在子类中完成的进度通过GUI中的进度条显示。
我现在所做的,我意识到将不起作用,是在父类中声明的事件方法定义作为每个子类将覆盖的虚拟方法。比如:
public abstract class Parent
{
public event EventHandler someEvent;
protected virtual void OnSomeEvent(object sender, EventArgs e)
{
EventHandler eh= someEvent;
if (eh!= null)
{
eh(this, e);
}
}
}
我的子类是这样的:
protected override void OnSomeEvent(object sender, EventArgs e)
{
base.OnSomeEvent(sender, e);
}
,事件在子类的某处引发。
然而,由于父类是抽象的,我将无法从GUI中侦听事件,因为我无法创建抽象类的实例。
我完全偏离了方向和/或有其他方法做到这一点吗?
您可以从子实例中附加到事件。
public abstract class Parent
{
public event Action Something;
public void OnSomething()
{
if (Something != null)
{
Something();
}
}
}
public class Child : Parent
{
}
Child c = new Child();
c.Something += () => Console.WriteLine("Got event from child");
c.OnSomething();
> Got event from child
您甚至可以将其声明为包含子类型的Parent
类型:
Parent c2 = new Child();
c2.Something += () => Console.WriteLine("Got event from Parent type");
c2.OnSomething();
> Got event from Parent type
抽象类只是一个代码模板,它被复制到从它继承的每个类中(简单地说)。可以这样想,所有的Child
类都包含Parent
中存在的代码的相同副本。
注意,这还将为Child
的每个实例生成一个唯一的事件处理程序。为所有源自Parent
的Child
设置一个静态事件处理程序,如下所示,并且不需要在Child
中编写任何代码:
public abstract class Parent
{
public static event Action Something;
public static void OnSomething()
{
if (Something != null)
{
Something();
}
}
}
然后,你可以这样做,例如:
Parent.Something += () => Console.WriteLine("This will be invoked twice.");
Child c = new Child();
Child c2 = new Child();
c.OnSomething();
c2.OnSomething();
> This will be invoked twice.
> This will be invoked twice.
这两个对象/事件调用将调用相同的事件处理程序,即使它们来自不同的子节点。
首先不要,因为someEvent
没有指定static
,所以子类的每个实例都将有自己的someEvent
。这意味着你得到的不是一个统一的观点,而是一个多元化的观点。这对于响应按钮被按下很有用,因为你不想在他们点击背景时以同样的方式响应。
通常不使用类层次结构,而是使用组合来处理这种情况。例如,将以下类添加到您的类:
public class ParentContainer
{
private List<Parent> watched = new List<Parent>();
public void Add(Parent watch)
{
watched.Add(watch);
watch.SomeEvent += Handler;
}
private void Handler(object sender, EventArgs args)
{
//Do something
}
}