【问题标题】:Make an independent duplication of a List<T>独立复制 List<T>
【发布时间】:2013-01-13 12:51:26
【问题描述】:

我创建了两个 List,分别称为 listAlistB。 我在 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?
    }

【问题讨论】:

标签: c#


【解决方案1】:

listA中的对象添加到listB时,您必须复制它们:

listB.AddRange(listA.Select(t => new Test { Name = t.Name }));

目前,您只是将listA 中的引用复制到listB 中,这些引用指向同一个对象。这就是为什么通过listA 修改它们会使更改在listB 中可见。

【讨论】:

  • 您可以将复制部分封装到一个方法中,称为Clone()
  • 谢谢李!我真正的 Test Clas 有 15 个属性。有没有比全部写出来的不同方法:listB.AddRange(listA.Select(t => new Test { Name = t.Name, Name2 = t.Name2 ... Name15 = t.Name15 }).ToList()) ; ?
【解决方案2】:

您必须创建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()));

【讨论】:

  • 使用 MemberwiseClone 对我来说是最好的方法。谢谢。
【解决方案3】:

这也有效,因为 listB 中的 Test obj 是一个不同于 listA 中的 Test obj 的实例

 listA.ForEach((item) =>
    {
        listB.Add(new Test {Name = item.Name});
    });

【讨论】:

    【解决方案4】:

    对于更复杂的对象,您可以实现上面评论中描述的克隆方法:

    public Test Clone()
    {
         return new Test { Name = this.Name};
    }
    

    上面的代码将被修改如下:

    listB.AddRange(listA.Select(t => t.Clone()));
    

    .NET 中也有一个 ICloneable 接口,但不推荐使用这个接口。我包含了另一个问题的链接,其中包含对此界面的讨论。

    Why should I implement ICloneable in c#?

    【讨论】:

      猜你喜欢
      • 2011-06-25
      • 2016-06-21
      • 1970-01-01
      • 2017-04-19
      • 2016-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      相关资源
      最近更新 更多