关于继承和循环依赖的问题

时间:2012-10-31 16:40:45

标签: c# inheritance dll

昨天在工作中遇到一个非常有趣的问题。

我有两个名为Foo和Bar的不同类。每个人都坐在自己的C#库项目中(单独的dll)。

Bar包含一个虚拟方法:

public class Bar
{
     public virtual void DoSomething();
}

Foo在其构造函数中使用Bar实例来设置内部属性:

public Foo (Bar myBar)
{
      m_Bar = myBar;
}

显然,Foo提到了Bar的项目。

现在,我有另外5个类,每个类也都位于自己的项目/ dll中。我们将它们称为A,B,C,D和E. A-E都是类Bar的子类,每个都包含它们自己的DoSomething()重写实现。因为它们是从Bar子类化的,所以它们中的任何一个都可以作为Foo构造函数的参数。

A-E各自维护一个Foo实例的内部集合。例如,我会在A类中做这样的事情:

myFooCollection.Add(new Foo(this));

因此,A-E类都需要引用Foo的项目/ dll。

现在,切换回Foo片刻让我们说在构造函数中设置Bar属性之后我需要调用该Bar的DoSomething()方法:

public class Foo (Bar myBar)
{
     m_Bar = myBar;
     m_Bar.DoSomething();
}

请记住,例如,A类被用作构造函数的Bar参数。我对DoSomething()的调用需要执行该方法的A实现。但是,由于构造函数参数是父类Bar,而Foo不知道类A-E(我不能在不引起循环依赖的情况下给它引用),它将在父类Bar中调用虚方法。在拨打电话之前,自然的解决方案是向子班级投降:

(A)m_Bar.DoSomething();

但这也是不可能的,因为再一次,Foo不知道这组子类。所以这就是我的困境。整个项目结构无法改变,因为系统显然比我在这里展示的更大更复杂。但我的要求仍然相同。 Foo需要能够到达DoSomething()的子实现才能正常运行。有关如何解决这个问题的任何想法?如果需要澄清以更好地理解问题,请告诉我,我会进一步详细说明。

1 个答案:

答案 0 :(得分:3)

您不得拥有项目的静态循环引用;但是,您可以拥有实例的动态循环引用。如果你调用m_Bar.DoSomething();那么,由于多态性,将自动调用正确的实现。如果m_BarBar,则会调用Bar的实现。如果m_BarA,则会调用A的实现。 BarFoo都不需要知道类AE的现有内容。


更新:(见下面的评论)

public class A : Bar
{
     public override void DoSomething()
     {
         Console.WriteLine("I am an 'A'");
     }
}