包含 class 个元素的列表的深层副本

Deep copy of a list with class elements

编辑: 对于将问题标记为重复的人。这个问题是关于如何创建深拷贝的。我的问题是如何确保在复制 class 元素列表时调用复制构造函数。

我正在尝试制作包含自定义 class 元素的列表的深层副本。如果我有一个字符串列表,我可以使用

List<string> secondList = new List<string>(firstList);

然后自由修改第二个列表中的元素而不影响第一个列表中的元素。但是,当我尝试对自定义 class 类型执行相同操作时,两个列表都会发生变化。为了尝试解决它,我制作了一个小测试程序,其中包含 class.

class TestClass
{
    public string name;

    public TestClass(string n)
    {
        name = n;
    }

    public TestClass(TestClass original)
    {
        name = original.name;
    }
}

我的程序所做的就是这个

TestClass t = new TestClass("Name1");
List<TestClass> list1 = new List<TestClass>();
list1.Add(t);

List<TestClass> list2 = new List<TestClass>(list1);
list2[0].name = "Name2";

最后一行代码更改了两个列表中第一个元素的名称,这是我不想要的。

这里的问题是您的对象是引用类型,而列表包含对这些对象的引用。

这意味着即使您的第二个列表具有第一个列表中引用的 COPY,这些引用仍指向原始对象。

为了解决这个问题,您必须克隆的不是列表中的引用,而是存储在列表中的实际对象。

您已经为 class 定义了一个复制构造函数,因此您可以使用它来制作列表的深度复制,如下所示:

var list2 = list1.Select(item => new TestClass(item)).ToList();

您使用这行代码创建引用:

List<TestClass> list2 = new List<TestClass>(list1);

但您不会喜欢使用 Call-by-Reference。您需要按价值呼叫 在这种方法中。

因此 lambda 表达式中的工作代码如下:

        TestClass t = new TestClass("Name1");
        List<TestClass> list1 = new List<TestClass>();
        list1.Add(t);

        List<TestClass> list2 = new List<TestClass>();
        list2 = list1.Select(item => new TestClass(item)).ToList();
        list2[0].name = "Name2";

玩得开心...