Faithium
Faithium

Reputation: 131

C# - Instantiate an object A where its constructor takes in parameter an object B that needs the reference of A (like One-to-One relationship)

I have a class A and B like this :

public class B {

    private A myA { get; }

    public B(A a) {
        myA = a;
    }
}

public class A {

    private B myB { get; }

    public A(B b) {
        myB = b;
    }
}

I would like to know if it is possible, in one instruction, to instantiate an A and a B at the same time without having to use

B b = new B();
A a = new A(b);
b.SetA();

or

A a = null;
a = new A(new B(a));

The reason I want to be able to do this in one instruction is because I want to be able to instatiate a class of type A in the constructor of another class like this

public abstract class SuperClass() {

    private A myA { get; }

    public SuperClass(A a) {
        myA = a;
    }
}

public class SpecificClassWithKnownValuesOfA() : SuperClass {

    public SpecificClassWithKnownValuesOfA() : base(/* here I want to use new A(new B(ref of a)) */) { }
}

Note that B.myA and A.myB are readonly properties as I don't want to put setters

Upvotes: 3

Views: 533

Answers (3)

Anduin Xue
Anduin Xue

Reputation: 3727

I have to say that you can't do this. I understand that you want to prevent getting an A without B, and prevent getting a B without A.

I suggest using the factory pattern with a private constructor.

For A:

    public class A
    {
        private B _b;
        public A(B b)
        {
            _b = b;
        }
    }

For B, do not create a public constructor. Use a builder to build it, so every time you get a B, there is always a fine instance in it.

    public class B
    {
        private A _a;
        private B() { }

        public (A, B) Init()
        {
            var b = new B();
            _a = new A(b);
            return (_a, b);
        }
    }

To get it, call:

var (a, b) = B.Init();

Upvotes: 2

Cid
Cid

Reputation: 15247

You can like this :

public class B {

    // This should be public with eventually a private setter
    public A myA { get; private set; }    

    public B(A a) {
        myA = a;
    }
}

public class A {

    public B myB { get; private set; }

    public A() {
        myB = new B(this);
    }
}

And then

A a = new A();

Upvotes: 0

Tim Rutter
Tim Rutter

Reputation: 4679

You could do this:

public class B {

    private A myA { get; public set; }

    public B() {}

    public B(A a) {
        myA = a;
        a.B = this;
    }
}

public class A {

    private B myB { get; public set; }

    public A(){}

    public A(B b) {
        myB = b;
        b.A = this;
    }
}


var a = new A(new B());

or alternatively

var b = new B(new A());

Whether its a good idea however is another question

Upvotes: 1

Related Questions