带有类元素的列表的深层副本

时间:2015-12-07 14:22:22

标签: c# list deep-copy

修改 对于将问题标记为重复的人。这个问题是关于如何创建深层副本。我的问题是如何确保在复制类元素列表时调用复制构造函数。

我正在尝试制作包含自定义类元素的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";

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

2 个答案:

答案 0 :(得分:2)

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

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

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

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

$.ajax({
type: "POST",
contentType : "application/json; charset=utf-8",
url: "../app/search/searchResults.ajax",
data: JSON.stringify(getJSONForm()),
dataType: 'json',
cache: false,
...

答案 1 :(得分:1)

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

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

但你不想使用Call-by-Reference。你需要按价值调用 在这种方法中。

所以lambda-expression中的工作代码如下:

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

玩得开心......