0

我想通过向它添加新的事件和方法来专门化一个基类。例如,B 类继承自 A 类。但是,如果在代码中我持有对 B 类实例的引用作为其基类型,A。每次我需要从 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;
    }
  }
}
4

2 回答 2

2

每次我需要从 B 访问某些东西时,我是否需要向下转换,例如订阅 EventB1,或调用 MethodB1?

绝对地。这应该告诉你这里有一种设计的味道。这并不意味着它一定很糟糕,但它至少应该促使您考虑是否有更清洁的方法。

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

如果不知道更多关于它试图做什么,很难说清楚。目前尚不清楚使用组合而不是继承是否会对您有所帮助,但这通常是值得考虑的事情。您可能还想考虑使用接口——两者都A可以B实现相同的接口,如果需要的话可以B组合一个。A也许。很难说:)

于 2012-07-31T08:14:28.993 回答
0

是的,要访问 B 类型的方法,您必须将对象转换为 B 类型。如果您绝对不想这样做,您可以使用反射来调用 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;
    }
  }
}
于 2012-07-31T08:31:03.013 回答