代码之家  ›  专栏  ›  技术社区  ›  Hassan Mokdad

如果清除原始列表,浅克隆列表中的项目会发生什么

  •  2
  • Hassan Mokdad  · 技术社区  · 8 年前

    我的初衷是通过TCPStream异步发送列表。但是,在将列表传递给异步线程之后,我需要直接清除它,以便再次用新数据填充它。因此,我使用Shallow cloning创建列表的副本,并将其传递给后台线程:

    private List<MyDataObject> GetShallowCloneOfDataList(List<MyDataObject> dataEvents)
    {
        return new List<MyDataObject>(dataEvents);
    }
    

    这是我最后的代码:

    List<MyDataObject> data = new List<MyDataObject>();
    while(hasMoreData)
    {
        data.clear(); 
        FillListFromServer(data);
        List<MyDataObject> clonedList = GetShallowCloneOfDataList(data);
        Task.Run(() => SendDataList(clonedList));
    }
    

    我的问题是,当我清除原始列表时 data ,克隆列表中的项目也会受到影响吗?测试我的代码表明,它们没有受到影响,但我不确定在处理大量数据(每秒20万)时,这种情况是否仍然存在。

    2 回复  |  直到 8 年前
        1
  •  4
  •   Community WizardZ    7 年前

    不,现有项目不会受到影响,除了可能符合垃圾回收的条件。

    这就像将变量设置为null一样,实际上:

    MyDataObject x = new MyDataObject(); // And populate
    MyDataObject y = x; // Just copy the reference
    x = null; // This doesn't change either y or the data in the object
    

    另一种思考方式是,如果你有一个地址簿,上面写满了你的朋友和家人的地址,然后把它扔到火上……你就再也找不到你的朋友或家人在哪里了,但这不会改变他们住的地方。(请参见 this answer 更多关于此类类比的信息。)

        2
  •  1
  •   Zein Makki    8 年前

    您决定创建一个新列表,该列表引用同一索引下的相同对象,即索引0处List1的引用与索引0处的List2的引用相同。

    现在您清除了第一个列表(它甚至不知道第二个列表的存在)。您的第二个列表保持不变!这里的商品数量没有什么区别。

    MyDataObject 是一个 class 而不是 struct ,然后更改列表中某个项的属性将更改另一个项中该项的属性。例子:

    data[0].Foo = 12;
    Console.WriteLine(clonedList[0].Foo); // prints 12
    

    但在显示的代码中似乎没有这样做。指出这一点,以防万一,你会在未来面对它。