将对象深层复制到List中

时间:2015-02-25 06:34:20

标签: c# .net deep-copy

我有一个循环:

List<A> list = new List<A>();
A obj = new A();

for (int i = 0; i < 10; ++i)
{
    obj.num = i; // Assigns the current i to the num attribute inside obj
    list.Add(obj);
}

但是,在这种情况下,每当我修改obj时,已经添加到obj的{​​{1}}的先前实例将被修改。如何编写代码,使得添加到列表中的内容不再引用list的当前值?

3 个答案:

答案 0 :(得分:3)

您可以通过 Linq 创建 List<A>,而不是添加:

List<A> list = Enumerable
  .Range(0, 10)
  .Select(i => new A() { num = i })
  .ToList();

如果您想要添加

List<A> list = new List<A>();

for (int i = 0; i < 10; ++i)
  list.Add(new A() {num = i}); // <- Adding new (copied) instance 

答案 1 :(得分:1)

你应该在for循环中移动obj变量的声明

List<A> list = new List<A>();

for (int i = 0; i < 10; ++i)
{
    A obj = new A();
    obj.num = i; // Assigns the current i to the num attribute inside obj
    list.Add(obj);
}

这只是变量范围。这里obj范围在for循环迭代中。如果你想在迭代之间使用一个变量,你应该像for循环声明obj那样定义for循环。

答案 2 :(得分:0)

这种情况正在发生,因为可能 A obj = new A();是一个ByReference对象。所以每当你进入循环时,它也会改变你在List上添加的对象。

你可以做的是

  1. 在循环内创建对象,然后添加它。

    for (int i = 0; i < 10; ++i)
    {
        A obj = new A(); // create here so it's a new object always
        obj.num = i; // Assigns the current i to the num attribute inside obj
        list.Add(obj);
    }
    
  2. 设置A类型IClonable

    class A : ICloneable
    {
        public object Clone()
        {
            return this.MemberwiseClone();
        }
    }
    
  3. 然后在添加之前插入。

    List<A> list = new List<A>();
    A obj = new A();
    obj.num = 0;
    
    for (int i = obj.num; i < 10; ++i)
    {
        var clonedObj = obj.Clone() as A; // cast to be able to add in the collection
        clonedObj.num = i;
        list.Add(clonedObj);
    }