如何解决循环引用?

如何解决循环引用问题,例如A类将B类作为其属性之一,而B类将A类作为其属性之一?

如何为这些问题做建筑师?

如果你举一个NHibernate的例子,对象之间会有一个父子关系。

它如何处理这些父子场景?

在大多数情况下,当我必须有两个东西相互引用时,我已经创建了一个接口来删除循环引用。 例如:

之前

public class Foo { Bar myBar; } public class Bar { Foo myFoo; } 

依赖图:

 Foo Bar ^ ^ | | Bar Foo 

Foo取决于Bar,但Bar也依赖于Foo。 如果它们位于单独的程序集中,则构建时会遇到问题,尤其是在执行干净重建时。

 public interface IBar { } public class Foo { IBar myBar; } public class Bar : IBar { Foo myFoo; } 

依赖图:

 Foo, IBar IBar ^ ^ | | Bar Foo 

Foo和Bar都依赖于IBar。 没有循环依赖,如果将IBar放在自己的程序集中,则Foo和Bar在单独的程序集中将不再是问题。

我会告诉你的朋友他需要重新考虑他的设计。 像你描述的循环引用通常是设计缺陷的代码味道。

与C ++(例如)不同,C#不需要前向声明来解析循环引用。 因此:

 public class A { public BB { get;set; } } public class B { public AA { get;set; } } 

然而,这通常是可疑设计决策的指标。

在大多数情况下,最好的解决方案是改变您的设计并避免循环依赖。 例如,您可以执行以下操作之一:

  1. 将公共引用代码移动到解决方案中的实用程序项目,并让其他项目引用Utility项目
  2. 在他的回答中使用“Ed Bayiates”所解释的界面。
  3. 如果它是少量的简单/公共代码,那么为其中一个类重写它,这样你就不需要在循环依赖中引用它。 (我最不喜欢的)

但是,如果您正在使用许多项目的解决方案,并且由于您不拥有代码而无法进行上述更改之一,则难以实现,或者不值得花时间修复,那么你可以使用这个方法:

右键单击项目引用,然后选择“添加引用…”。 然后在出现的对话框窗口中切换到“浏览”选项卡和“浏览”按钮。 从那里你可以找到DLL并选择它。 这是最好的解决方法,并且可能导致构建问题,尤其是如果两个DLL都经常更新和/或具有许多依赖项。 我不推荐这种方法,但它适用于捏。

Fissh

接口是一个好主意但是如果你寻找一个更快的解决方案,而不是重做这么多东西的架构,试着构建一个包含所有数据结构的dll类库,你的主项目会保存你需要那些数据的UI,然后是你想要的任何其他dll添加可以访问数据结构dll,因此他们拥有运行所需的所有信息,但仍然可以分开 – 这称为三力设计模式 –