C# 三个类之间的循环引用
我有三个类,它们之间有一个循环引用C# 三个类之间的循环引用,c#,class,circular-reference,C#,Class,Circular Reference,我有三个类,它们之间有一个循环引用 class A { public A() { B obj = new B(); } } class B { public B() { C obj = new C(); } } class C { public C() { A obj = new A(); } } 当我创建一个A的对象时,它抛出了一个异常 如何创建循环引用彼此的类实例 当我
class A
{
public A()
{
B obj = new B();
}
}
class B
{
public B()
{
C obj = new C();
}
}
class C
{
public C()
{
A obj = new A();
}
}
当我创建一个A
的对象时,它抛出了一个异常如何创建循环引用彼此的类实例 当我创建一个对象时,它会抛出异常 是的,会的。创建
A
创建一个新的B
,它创建一个新的C
,它创建一个新的A
等
如何解析循环引用
大概您希望C
构造函数了解原始A
?如果是,有两种选择:
- 分别构建这三个,然后告诉他们彼此的情况。这要求类型是可变的
- 将
此
从
构造函数传递到A
构造函数,然后将其从B
构造函数传递到B
构造函数。就允许C
逃逸This
的构造函数而言,这是令人讨厌的,应该非常小心地进行。(A
和B
在实例有机会完成初始化之前,不应调用实例上的任何方法。)C
class A
{
public B b;
public A()
{
this.b = new B(new C(this));
}
}
class B
{
public C c;
public B(C c)
{
this.c = c;
}
}
class C
{
public A a;
public C(A a)
{
this.a = a;
}
}
最简单的方法是创建一个接口IA,它定义了类A的公共接口,然后让类A实现接口IA。
然后添加一个工厂类,该类可以创建的实例并返回IA。这样,C类就不需要知道A类,循环引用被破坏。您也可以尝试加载对象。这样,它们实际上不会立即被构造,也不会进入构造的循环,而是在您实际需要它们时被构造
您可以尝试在MSDN文章中使用C#的
Lazy
实现,或者使用get{}
循环引用或stackoverflow异常在access上进行构造,您可以通过删除循环引用来解决此问题:)如果我最终遇到类似的情况,我将回顾代码的体系结构。当对象C发生变化时,它会告诉A,A决定它发生了变化,B决定它发生了变化,C决定它发生了变化,并告诉。。。。这似乎是一个相当常见的问题(尽管通常对象较多,但类较少)。你是创建了一个不可用的对象,还是在构造函数中泄漏了this
?这个解决方案不是很好,因为你把这些类紧密地结合在一起。接下来的问题是,为什么首先要使用不同的类?如果您确实需要不同的类,您不应该将它们紧密地耦合在一起,以至于需要将对这些类的引用传递到构造函数中。@JonathanvandeVeen类的耦合在这里并没有真正改变。简单地说:它现在起作用了。它们以前是同等耦合的,但还有一个缺点就是不工作。没错,除了你正在处理一个闻起来像糟糕设计的东西,因此我认为你应该采用更好的设计。添加额外的接口、接口实现和工厂:并不真的符合我对“最简单”的定义。这是一个公平的建议,别误会我的意思——我只是在琢磨“最容易”这个词的用法。明白了。不过,对大多数人来说,这比实现依赖注入更容易,因为依赖注入是我首选的解决方案。他们说在构造函数之间从一个类传递到另一个类的解决方案是我不能接受的,所以对我来说,这算不上真正的解决方案。非常快。哈哈,回答时间和思维过程都很疯狂。