具有类元素的列表的深度副本

本文关键字:列表 副本 深度 元素 | 更新日期: 2023-09-27 18:26:08

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

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

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

然后自由地修改第二列表中的元素,而不影响第一列表中的那些元素。但是,当我尝试对自定义类类型执行同样的操作时,两个列表都会发生更改。为了解决这个问题,我制作了一个只有这个类的小测试程序。

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,这些引用仍然指向原始对象。

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

您已经为类定义了一个复制构造函数,因此您可以使用它对列表进行如下深度复制:

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

使用以下代码行创建引用:

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

但您不喜欢使用"按引用调用"。您需要按价值呼叫在这种方法中。

因此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";

玩得开心…