我有一个带有几个子类的父抽象类。最后,我希望通过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中侦听事件,因为我无法创建抽象类的实例。
我完全偏离正轨和/或是否有其他方法可以做到这一点?
答案 0 :(得分:2)
您可以从子实例附加到事件。
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
的每个实例生成唯一的事件处理程序。为Child
派生的所有Parent
提供静态事件处理程序将如下所示,并且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.
这两个对象/事件调用都将调用相同的事件处理程序,即使它们来自不同的子对象。
答案 1 :(得分:0)
首先要做的是,因为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
}
}