向下转换以访问子类中的其他事件和方法

时间:2012-07-31 08:09:12

标签: c# .net winforms

我想通过向其添加新事件和方法来专门化基类。例如,B类继承自A类。但是,如果在代码中我持有对我的B类实例的引用作为其基本类型,那么我每次需要从B中访问它时需要向下转发,例如:订阅EventB1,还是调用MethodB1?

if (obj is B) 
{ 
  B m = (B)obj;
  m.EventB1 += EventHandlerB1; 
}

另外,如果我在我的基类中有一个switch语句,如上所述。在B中添加更多案例是不好的做法吗?

Class A
{
  public event EventHandler EventA1

  public void MethodA1()
  {
    //some code
  }

  protected virtual void ProcessWorkItem(workItem type)
  {
    switch (type)
    {
      case workItem.A1:
        ..
        break;
      case workItem.A2:
        ..
        break;
      case workItem.A3:
        ..
        break;
    }
  }
}

Class B : A
{
  public event EventHandler EventB1

  public void MethodB1()
  {
    //some code
  }

  protected override void ProcessWorkItem(workItem type)
  {
    base.ProcessWorkItem(type);

    switch (type)
    {
      case workItem.B1:
        ..
        break;
      case workItem.B2:
        ..
        break;
      case workItem.B3:
        ..
        break;
    }
  }
}

2 个答案:

答案 0 :(得分:2)

  

每次我需要从B中访问某些内容时,我需要向下转发,例如订阅EventB1,还是调用MethodB1?

绝对。这应该告诉你这里有一种设计气味。这并不意味着必然坏,但它至少应该提示您考虑是否采用更清洁的方法。

  

另外,如果我在我的基类中有一个switch语句,如上所述。在B中添加更多案例是不好的做法吗?

如果不了解更多关于它正在尝试做什么的话,很难说清楚。目前尚不清楚使用构图而不是继承会对你有所帮助,但它通常值得思考。您可能还需要考虑使用接口 - AB都可以实现相同的接口,如果需要,B组成A。也许。很难说:))

答案 1 :(得分:0)

是的,要访问B类方法,您必须将对象转换为B类。 如果您绝对不想这样做,可以使用Reflection来调用repsective方法。但是,如果不了解更多关于你想做什么的话,我不建议这样做。

此外,与事件相关的是:如果要调用事件,则必须从声明它的类中实现的代码中执行此操作。

关于转换:我认为这取决于。第一件事......我会使用覆盖,然后根据此功能的作用/服务,调用base或不使用。

此致 马丁

Class A
{
  public event EventHandler EventA1

  public void MethodA1()
  {
    //some code
  }

  protected virtual void FireEventA1()
  {
    if (EventA1 != null)
      EventA1(new EventArgs());
  }


  protected virtual void ProcessWorkItem(workItem type)
  {
    switch (type)
    {
      case workItem.A1:
        ..
        break;
      case workItem.A2:
        ..
        break;
      case workItem.A3:
        ..
        break;
    }
  }
}

Class B : A
{
  public event EventHandler EventB1

  public void MethodB1()
  {
    //some code
  }

  protected virtual void FireEventB1()
  {
    if (EventB1 != null)
      EventB1(new EventArgs());
  }

  protected override void ProcessWorkItem(workItem type)
  {
    base.ProcessWorkItem(type);
    switch (type)
    {
      case workItem.B1:
        ..
        break;
      case workItem.B2:
        ..
        break;
      case workItem.B3:
        ..
        break;
    }
  }
}