-1

I have three classes and I have a circular reference between them.

class A 
{
    public A()
    {
        B obj = new B();
    }
}
class B
{
    public B()
    {
        C obj = new C();
    }
}
class C
{
    public C()
    {
        A obj = new A();
    }
}

When I create an object of A, it's throwing an exception.
How I can create classes instances circularly referencing each other?

Volodymyr
  • 1,209
  • 1
  • 15
  • 26
pchajer
  • 1,584
  • 2
  • 13
  • 25
  • 2
    Circular reference, or stackoverflow exception? – J. Steen Jul 19 '12 at 11:27
  • 2
    You could resolve it removing by removing the circular reference :) – Paolo Moretti Jul 19 '12 at 11:29
  • If I ever end up with something like this, I'll review architecture of my code. – Leri Jul 19 '12 at 11:33
  • And when object C changes, it tells A, which decides _it's_ changed and tells B, which decides _it's_ changed and tells C, which decides _it's changed, and tells.... Seems a rather common problem (though often with more objects but fewer classes). And do you create an unusable object, or leak `this` in the constructor? – RalphChapin Jul 19 '12 at 19:01

5 Answers5

5

When I am creating object of A it's throwing exception

Well yes, it would. Creating A creates a new B which creates a new C, which creates a new A etc.

How could I resolve the circular reference.

Presumably you want the C constructor to know about the original A? If so, there are two options:

  • Construct all three separately, then tell them about each other. This requires the types to be mutable.
  • Pass this from the A constructor to the B constructor, and then pass it on from the B constructor to the C constructor. This is nasty in terms of allowing this to escape A's constructor, and should be done very carefully. (B and C shouldn't call any methods on the instance before it's had a chance to finish initializing.)
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
4

You can do this:

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;
    }
}
Razvi
  • 2,808
  • 5
  • 31
  • 39
  • This solution is not so good as you very tightly couple these classes. The question then becomes, why use different classes in the first place? If you do need different classes you should not couple them so tightly as that you need a reference to this passed into a constructor. – Jonathan van de Veen Jul 19 '12 at 11:32
  • 4
    @JonathanvandeVeen the coupling of the classes hasn't really changed here. Simply: it now works. They were equally coupled before, but with the additional downside of *not working*. – Marc Gravell Jul 19 '12 at 11:38
  • True, except you're working around something that smells like bad design in the first place, hence I think you should go with a better design. – Jonathan van de Veen Jul 19 '12 at 13:48
2

The easiest way that is still neat, is to create an interface IA which defines the public interface for class A. Then make class A implement interface IA. Then add a factory class that can create an instance of A and returns an IA. This way class C does not need to know about class A and the circular reference is broken.

Jonathan van de Veen
  • 1,016
  • 13
  • 27
  • Adding extra interfaces, an interface implementation, and a factory: doesn't really meet my definition of "easiest". It is a fair suggestion, don't get me wrong - I'm just quibbling the use of the word "easiest". – Marc Gravell Jul 19 '12 at 11:39
  • Point taken. To most this is easier than implementing dependency injection, though, which would me by preferred solution. The solution where they say to pass a reference between constructors from one class to another is not acceptable to me, so for me that does not count as a real solution. – Jonathan van de Veen Jul 19 '12 at 13:45
2

You could also try and load the objects lazily. That way, they won't actually be constructed immediately and won't get into a circular loop of constructs, but rather be constructed when you actually need them.

You could try using C#'s Lazy<T> implementation in the MSDN article, or something involving properties by constructing on access with get{ }.

Naltharial
  • 2,132
  • 14
  • 21
0

When u call the constructor of A,B or C you always will get an exception. Maybe you can solve it by passing a paramter to the constructor, but i'm wondering what you want to do with this structure. Can u tell me please?

Tomtom
  • 9,087
  • 7
  • 52
  • 95