C# 子/父事件引发

C# 子/父事件引发,c#,events,inheritance,C#,Events,Inheritance,我有一个父抽象类和几个子类。最后,我希望通过GUI中的进度条显示在children类中完成的进度 我现在所做的是在父类中声明为虚拟方法的事件方法定义,每个子类都将覆盖它,我意识到这是行不通的。比如: public abstract class Parent { public event EventHandler someEvent; protected virtual void OnSomeEvent(object sender, EventArgs e) {

我有一个父抽象类和几个子类。最后,我希望通过GUI中的进度条显示在children类中完成的进度

我现在所做的是在父类中声明为虚拟方法的事件方法定义,每个子类都将覆盖它,我意识到这是行不通的。比如:

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);
    }
我的孩子们的课程有:

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 c2 = new Child();
c2.Something += () => Console.WriteLine("Got event from Parent type");
c2.OnSomething();
> Got event from Parent type
抽象类只是一个代码模板,它被复制到从它继承的每个类中(简单地说)。想象一下,您的所有
子类
都包含一个与
父类
中存在的代码相同的副本


请注意,这还将为
子对象的每个实例生成唯一的事件处理程序。对于从父级派生的所有子级
都有一个静态事件处理程序,看起来是这样的,并且子级中不需要任何代码:

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
    }
}
公共类父容器
{
监视的私有列表=新列表();
公共无效添加(父监视)
{
watched.Add(watch);
watch.SomeEvent+=处理程序;
}
私有void处理程序(对象发送方、事件args args)
{
//做点什么
}
}

为什么您的UI不能附加到子实例上的事件?如果您继承自
父级
子级
也将拥有该事件。我的想法是,我不一定希望GUI知道是哪个子级引发了该事件@SpikeXSo您想要在父级上有一个只有一个实例的静态事件处理程序,这就是您要说的。我希望每个子级都有一个进度条,这样您的解决方案才是正确的@SpikeXPossible重复的。请澄清,您在子类中对OnSomething()的实现是什么?@moalaz没有。它自动从父级继承。您可以调用
OnSomething()子对象中调用code>,但默认情况下,它将只调用
某物
事件。@moalaz我还为静态事件添加了一些代码,如果您不希望事件处理程序对每个
子对象
实例都是唯一的。