简体   繁体   中英

If I make a list from a dictionary and if I change a property from an object of the list, will it show on the dictionary?

I have a dictionary like this:

private Dictionary<string, TestObject> example = new Dictionary<string, TestObject>() {
            { "object1", new TestObject()},
            { "object2", new TestObject()}
        };

and I make a list:

internal List<TestObject> exampleList = example.Values.Where(x => x != null).Select(a => a).ToList();

TestObject is something like this

class TestObject{
    string name = "phil";
    public void SetName(string name){
          this.name = name;
    }
}

So, if I do something like this:

foreach(TestObject object in exampleList){
    object.SetName("Arthur");
}

will the value also change in the dictionary?

TestObject is a class - so it is a reference type. When you create the list from the dictionary you just pass references to the objects which live in the heap (you can think about references as links). You are not passing objects here. Even dictionary does not hold objects - it holds only references to objects. You can have many references which point to the same object. And you can modify object via any of references. But the object is only one.

will the value also change in the dictionary?

Yes, it will. The following picture explains why

在此处输入图片说明

As you can see, dictionary, list and @object variable on the stack - all reference same TestObject instance on the heap (three references). If you'll use any of the references to modify the TestObject name, that will update single TestObject instance.

Note that dictionary Entry is a struct (value type) thus its value is stored in the array directly instead of storing reference.

Further reading: .NET Type Fundamentals

Short answer: Yes .

You did not make a copy of the TestObject objects : you simply generated a list with references to these objects.

In order to make copies, you should add a Clone() method to your TestObject class, and make a clone in the .Select(..) part of the LINQ query.

For example:

class TestObject{
    string name = "phil";

    public void SetName(string name){
          this.name = name;
    }

    
}

And then use:

example.Values.Where(x => x != null).Select(a => a).ToList();

Note that in this case, we performed a shallow clone: the new TestObject referes to the same string object. For string s that's not a problem since these are immutables. It can be useful to make a deep clone where all the members are cloned as well (up to primitives).

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