简体   繁体   English

为什么不更新该对象?

[英]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? 在C#中,如果我在一个类中有一个对象变量,而第二个类具有设置为同一对象的对象变量,那么当第二个类更改了对象变量时,如何更新两个对象变量呢?

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. 在上面的代码中,更改class2.objclass1.obj保持不变。 How is it possible for class1.obj to have the same value as class2.obj when any value is set to the class2.obj ? 这怎么可能class1.obj具有相同的价值class2.obj当任何值被设置为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. class2.obj不是值。 It's a reference to an object. 它是对对象的引用。 Before you call class2.obj = "test2" , class2.obj contains a reference to the string "test". 在调用class2.obj = "test2"class2.obj包含对字符串“ test”的引用。

Then you're changing it to reference a different object - the string "test2". 然后,您将其更改为引用另一个对象-字符串“ test2”。 class1.obj still points to the same object it did, which is a different object, the string "test." class1.obj仍指向它所做的相同对象,即另一个对象,即字符串“ 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 . 这将创建一个新的变量,该变量指向与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上设置一个属性,那么我也在thing1上设置它,因为它们都是同一对象。

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 . thing3不会为null It's still pointing to that same object. 它仍然指向同一对象。

You are trowing the value from class2.obj away when doing 您trowing从价值class2.obj时做掉

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 . 另外,如果class1.obj是一个对象,并且可以在class1.objclass2.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: 通过将字符串文字分配给String变量,您实际上是在实例化一个新的字符串对象并分配给现有的对象:

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. 请注意, Class1.obj的值未更改。 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. 在这里,您是将值从class1.obj分配给class2.obj,而不更改其引用。 Therefore class1.obj value will not change when class2.obj value changes. 因此,当class2.obj值更改时,class1.obj值将不会更改。

This will not work, try using something like : 这将无法正常工作,请尝试使用类似以下内容的方法:

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

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

a = b;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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