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

What will happen to the items inside a shallow cloned list if the original list was cleared

我的初衷是通过 TCP 流异步发送列表。但是在将列表传递给异步线程之后,我需要立即清除它以再次用新数据填充它。所以我使用浅克隆来创建列表的副本,并将其传递给后台线程:

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时,克隆列表中的项目是否也会受到影响?测试我的代码显示它们没有受到影响,但我不确定在处理大量数据(每秒 200K)时这是否会保持不变。

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

这就像将变量设置为 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。)

所以让我们这样考虑。你在内存中有对象,你有一个列表,其中每个索引引用内存中的这些对象之一。

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

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

您唯一需要关心的是,如果 MyDataObjectclass 而不是 struct,则更改列表中某项的属性会更改它在另一个。示例:

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

但是您似乎没有在显示的代码中执行此操作。指出这一点,以防您将来遇到它。