为什么这个方法不产生List的深拷贝?

问题描述 投票:0回答:1

在此线程中:
如何创建列表的新深层副本(克隆)

提问者的例子是如何创建他们的列表的深层副本。我没有看到任何人提供关于为什么它不起作用的见解。为什么新列表表现为对旧列表的引用? (或者至少是元素)。

我了解引用在 C++ 中的工作原理,并且我认为它们在 C# 中的行为方式是相似的。但也许我错过了一些东西。我还是 C# 新手。

这是您可以粘贴并运行的简化版本:

namespace OOPtest1
{
    internal class Program
    {
        public class Book
        {
            public string title = "";

            public Book(string title)
            {
                this.title = title;
            }
        }
        
       
        static void Main(string[] args)
        {
            //InitializeComponent();

            List<Book> books_1 = new List<Book>();
            books_1.Add(new Book("One"));
            books_1.Add(new Book("Two"));
            books_1.Add(new Book("Three"));
            books_1.Add(new Book("Four"));

            List<Book> books_2 = new List<Book>(books_1);

            books_2[0].title = "Five"; // this changes the books_1 element as well
            books_2[1].title = "Six"; // this changes the books_1 element as well

        }   
    
    }
}

我希望这会表现得像一个完全不同的集合。

c# deep-copy
1个回答
0
投票

首先请注意,

Book
是引用类型,因此对该类型实例的引用存储在
books_1
books_2
中。

当您将

books_1
的内容复制到
books_2
时,您已将 references 复制到
Book
对象,而不是对象本身的 contents

所以复制后,每个列表的第一个元素的情况如下:

books_1[0]----\
               \ 
             {Book0}   
               /
books_2[0]----/

现在您应该能够看到,当您更改

books_1[0].title
时,您将更改
Book0.title
- 并且因为
books_2[0]
引用了同一个对象,所以它也会更改该引用 - 因为它引用同一个对象.

如果您认为引用更像 C++ 指针,那么您应该得到它。

© www.soinside.com 2019 - 2024. All rights reserved.