我制作了两个List<试验>称为 listA 和 listB 。 我在 listA 中保存了数据的和平。 我将数据从 listA 复制到 listB 。 我更改 listB 中的数据。 当我更改 listB 中的数据时,它也会在 listA 中更改 - 是否可以避免这种情况?
我希望你能帮助我:o)
public class Test
{
public string Name { get; set; }
}
static void Test()
{
List<Test> listA = new List<Test>();
List<Test> listB = new List<Test>();
listA.Add(new Test { Name = "A" });
listB.AddRange(listA);
//I change the data in listB and the data in listA also get changed.
listB.First().Name = "B";
Console.WriteLine("listA: {0} listB: {1}", listA.First().Name, listB.First().Name);
//Can I avoid the change of data in listA?
}
答案 0 :(得分:8)
将listA
中的对象添加到listB
时,您必须复制这些对象:
listB.AddRange(listA.Select(t => new Test { Name = t.Name }));
目前,您只是将listA
中的引用复制到listB
,这些引用指向同一个对象。这就是为什么通过listA
修改它们会使更改在listB
中可见。
答案 1 :(得分:1)
您必须创建Test
对象的新实例。
您可以在测试类中添加一个复制方法,以便使用MemberwiseClone
更轻松地复制成员,如果您丢失要复制的属性而不需要填充每个属性,那么这将很好属性。
public class Test
{
public string Name { get; set; }
public Test Copy()
{
return (Test)this.MemberwiseClone();
}
}
然后您可以在代码中的所需位置使用。
List<Test> listA = new List<Test>();
List<Test> listB = new List<Test>();
listA.Add(new Test { Name = "A" });
listB.AddRange(listA.Select(x => x.Copy()));
答案 2 :(得分:0)
这也有效,因为listB中的Test obj是一个与listA
中的Test obj不同的实例 listA.ForEach((item) =>
{
listB.Add(new Test {Name = item.Name});
});
答案 3 :(得分:0)
对于更复杂的对象,您可以实现克隆方法,如上面的注释中所述:
public Test Clone()
{
return new Test { Name = this.Name};
}
上面的代码将修改如下:
listB.AddRange(listA.Select(t => t.Clone()));
.NET中还有一个ICloneable接口,但不建议使用此接口。我包含了另一个问题的链接,其中包含对此界面的讨论。