【问题标题】:Child/Parent event raising孩子/家长事件提升
【发布时间】:2013-06-03 16:47:27
【问题描述】:

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

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

【问题讨论】:

  • 为什么您的 UI 不能附加到子实例上的事件?如果你继承自ParentChild 也会有这个事件。
  • 这个想法是我不一定希望 GUI 知道哪个孩子引发了事件。 @SpikeX
  • 所以你想要一个在 Parent 上的静态事件处理程序,它只有一个实例,这就是你的意思。
  • 我想要每个孩子都有一个进度条,所以你的解决方案是正确的@SpikeX

标签: c# events inheritance


【解决方案1】:

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

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 派生的所有Childs 提供一个静态事件处理程序看起来像这样,并且不需要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.

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

【讨论】:

  • 明确一点,您在子类中的 OnSomething() 实现是什么?
  • @moalaz 没有。它自动继承自Parent。您可以从Child 中调用OnSomething();,除非您特别想用其他行为覆盖它,但默认情况下,它只会调用Something 事件。
  • @moalaz 如果您不希望事件处理程序对每个 Child 实例都是唯一的,我还为静态事件添加了一些代码。
【解决方案2】:

首先不要,因为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
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多