1

I have 2 data classes:

class A
{
    public int n { get; set; }
}
class B
{
    public A obj { get; set; }
}

And in the main program, I create an B object and assign value to B.obj like this:

A a = new A() { n = 1 };
B b = new B() { obj = a };

It looks good until here, but when I assign a new value to a like this:

a = new A() { n = 5 };

and then check b.obj again but the value is still 1 but not 5

I know that objects in C# are reference type so I thought b.obj always refers to memory address of object a, but it seems it's not...

Is there any way to make b.obj always refer to memory of object a?

Cleo Ku
  • 11
  • 2
  • 1
    See, `a.n = 5;` would affect `b.obj` because `a` and `obj` both refer to the same object in memory, but `a = new A() { n = 5 };` points `a` at a new instance of `A()`. What is your reason for wanting to do this? P.S. Some people think [so] is "unfriendly" because we ask questions like this, but generally we just want to understand your use case better so that we can find a solution that works for you and fits within the confines of the language. I'm just trying to better understand your goals. – ProgrammingLlama Jun 16 '23 at 04:23
  • 1
    Does this answer your question? [Fields of class, are they stored in the stack or heap?](https://stackoverflow.com/questions/2565331/fields-of-class-are-they-stored-in-the-stack-or-heap) – shingo Jun 16 '23 at 04:27
  • There is a nested data structure with 4 layers: A() { B() { C() { D() { } } } }, and i want to update C.D to a totally new D instance directly, but not to assign value to it by A.B.C.D = new D() {} – Cleo Ku Jun 16 '23 at 04:27
  • Does adding a method on `A` work for you? So instead of `A.B.C.D = new D() { }` you could call `A.SetD(new D() { })`? – ProgrammingLlama Jun 16 '23 at 04:30
  • I'll try it!! Thanks for your advice :) – Cleo Ku Jun 16 '23 at 04:46
  • It's important to realize the difference between variables and objects. After your first two statements, you have created two objects, an `A` and a `B`. You have two variables `a` and `b` which refer to those to objects. But, your `A` object is also referred to by a property (`obj`) of your `B` object. Your third statement instantiated a third object (a second `A` instance). The variable `a` now refers to that new instance, but `b.obj` still refers to the original `A` instance - i.e., `a` and `b.obj` both refer to `A` instances, but different ones. – Flydog57 Jun 16 '23 at 04:54

1 Answers1

0

I think the easiest way to do this is to simply add a method to A that simplifies setting D:

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

    public void SetD(D value)
    {
        this.B.C.D = value;
    }
}
ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
  • Which will throw if `B` is `null` – Fildor Jun 16 '23 at 05:18
  • 1
    @Fildor Indeed, but it's up to OP to ensure that all objects are instantiated. `A.B.C.D = new D() { };` (which is what it sounds like OP is currently doing) would equally throw if `B` is `null`. If OP is using nullable reference types, they could declare `B` as `public required B B { get; set; }` and do the same in B for C, and the same in C for D to ensure they get set. – ProgrammingLlama Jun 16 '23 at 05:26
  • I just thought it was worth giving a heads up. – Fildor Jun 16 '23 at 05:51
  • 1
    @Fildor Yep, you're right. :) – ProgrammingLlama Jun 16 '23 at 06:02