简体   繁体   中英

Why is this object not being updated?

In C#, if I have an object variable in a class, and a second class has an object variable that is set to the same object, how can both object variables be updated when the second class has the object variable changed?

Here is some code as an example:

public class Class1
{
    public object obj { get; set; }
}

public class Class2
{
    public object obj { get; set; }
}

private void SetObject()
{
    var class1 = new Class1();
    class1.obj = "test";

    var class2 = new Class2();
    class2.obj = class1.obj;

    class2.obj = "test2";
}

In the above code, when changing the class2.obj , the class1.obj stays the same. How is it possible for class1.obj to have the same value as class2.obj when any value is set to the class2.obj ?

Edit: I added a blog post that hopefully explains and demonstrates more clearly. Please don't be offended because it says "for absolute beginners." I don't know what your background/experience is, but I like to write from that perspective.


class2.obj isn't a value. It's a reference to an object. Before you call class2.obj = "test2" , class2.obj contains a reference to the string "test".

Then you're changing it to reference a different object - the string "test2". class1.obj still points to the same object it did, which is a different object, the string "test."

If they were both pointing to the same object and you changed a property of that object you'd see the change reflected in both places, because then there would be two variables each referencing the same object.

This clicks once you get it, but I think an example is required to do it justice.

Suppose we have this class:

public class ThingWithValue
{
    public string Value { get; set; }
}

And we create a few instances of it:

var thing1 = new ThingWithValue { Value = "A" };
var thing2 = new ThingWithValue { Value = "B" };

This creates a new variable pointing to the same object as thing1 . There are two variables but only one object:

var thing3 = thing1;

So if I set a property on thing3 then I'm also setting it on thing1 because they're both the same object.

thing3.Value = "C";

But if I do this:

thing1 = null;

then the only thing I'm changing is the variable - it no longer points to that object. I'm not changing that object. It still exists. thing3 wouldn't become null . It's still pointing to that same object.

You are trowing the value from class2.obj away when doing

class2.obj = "test2";

Also, you could change it if class1.obj were an object and you change a property of it either on class1.obj or class2.obj . Not reassigning another object.

Here in your case you are indirectly doing the operation with string, the class object is not being mapped or assigned. Hence it is similar o the following:

string s1 = "abc";
string s2 = s1;
s2 = "123";
// this wont change the value of s1;

By assigning a string literal to a String variable, You are actually instantiate a new string object and assigned to the existing one:

What you are actually expected is that:

var class1Object1 = new Class1();
class1Object1.obj = "test";
var class1Object2 = new Class1();
class1Object2 = class1Object1;
class1Object2.obj = "test2";

Here you are creating two different instances of the class and assign one to another. so that changes in one object will reflect in the other too. but this is not possible in the case of strings since they are immutable.

It won't update the other variable because you're actually modifying the pointer , rather than the object.

For example, after running this

class1.obj = "test";

We can imagine the memory layout as follows:

Mem Address  Name        Value
0x0001       Class1.obj  0x0003
0x0002       Class2.obj 
0x0003       string      "test"

Then we run:

class2.obj = class1.obj;

So now the memory looks like:

Mem Address  Name        Value
0x0001       Class1.obj  0x0003
0x0002       Class2.obj  0x0003
0x0003       string      "test"

And finally:

class2.obj = "test2";

Gives us this:

Mem Address  Name        Value
0x0001       Class1.obj  0x0003
0x0002       Class2.obj  0x0004
0x0003       string      "test"
0x0004       string      "test2"

Note that Class1.obj 's value has not been changed. It's still pointing to the original object.

class2.obj = class1.obj;

Here you are assigning value from class1.obj to the class2.obj, not changing its reference. Therefore class1.obj value will not change when class2.obj value changes.

This will not work, try using something like :

myclass a = new myclass();
a.integer = 1;

myclass b = new myclass();
b.integer = 2;

a = b;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM