儿童/家长活动

时间:2013-06-03 16:47:27

标签: c# events inheritance

我有一个带有几个子类的父抽象类。最后,我希望通过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中侦听事件,因为我无法创建抽象类的实例。

我完全偏离正轨和/或是否有其他方法可以做到这一点?

2 个答案:

答案 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
    }
}