3

I have a parent abstract class with several children classes. Eventually, I would like the progress done in the children classes to be shown via a progress bar in the GUI.

What I currently have done right now, which I am realizing will not work, is the event method definition declared in the parent class as a virtual method which each child class will overwrite. So something like :

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);
        }
    }
}

And my child classes have something like :

  protected override void OnSomeEvent(object sender, EventArgs e)
    {
        base.OnSomeEvent(sender, e);
    }

and the event is raised somewhere in the child class.

However, seeing as the parent class is abstract, I will not be able to listen to the event from my GUI because I can not create an instance of an abstract class.

Am I completely off course and/or is there another method of doing this?

4

2 回答 2

3

您可以从子实例附加到事件。

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为所有派生自的 s提供一个静态事件处理程序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.

这两个对象/事件调用都将调用相同的事件处理程序,即使它们来自不同的孩子。

于 2013-06-03T16:52:12.677 回答
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
    }
}
于 2013-06-03T16:55:19.233 回答