何时更合适创建新列表而不是清空现有列表?

4
给定一个列表:
List<myType> myList = new List<myType>();

在运行时修改集合内容后,为了清空列表,我看到一些示例建议使用:
```python some_list.clear() ```
其中 `some_list` 是要清空的列表。
myList = new List<myType>();

相比之下
myList.Clear();

我可以想到很多原因,为什么我更喜欢其中一种方法而不是另一种,但是是否存在其他良好的基准或指南来确定何时应优先选择一种方法呢?

3个回答

3
如果列表很大(80千字节或更大),那么它将存储在大对象堆上。LOH的官方指导是尽可能多地重复使用对象,以减少堆碎片。LOH不像常规堆一样紧凑。对于较小的列表,我发现创建一个新列表通常比调用Clear更快。这并非总是如此,因此最好在应用程序中两种方式进行测试。如果调用Clear,它只会将列表中的所有项设置为默认值,并将Count设置为0。它不会更改列表的容量。因此,调用Clear不会更改分配给集合的内存量。如果您想清除列表并减小其大小,请调用Clear,然后调用TrimExcess
如果您不小心的话,可能会遇到别名问题。如果您有多个对象引用同一个列表,则创建新列表不会删除这些其他引用。因此,最终会得到两个列表。这只是需要考虑的一点。
总的来说,我认为这方面没有特定的“最佳实践”。我发现有时使用“Clear”很好,有时最好分配一个新列表。

+1 这与我所寻找的更一致。谢谢。你有关于LOH的链接吗? - Matthew
@Matthew:看一下我刚刚添加的链接。有一篇关于CLR Inside Out的好文章。 - Jim Mischel
我知道这是一个老问题,但它刚被链接为重复项并阅读答案让我想到了一些问题...当你谈论列表的大小时,它是如何计算的?大概列表的大小不是列表内容的大小,因为它们都将是引用(如果它是引用类型的列表),所以它只是所有引用的大小(我记不清那会有多大)...? - Chris
@Chris:列表的大小将是其Capacity乘以引用类型的大小(假设它是引用类型的列表),再加上一小部分开销(少于100字节)。在32位运行时中,一个引用占4个字节,在64位运行时中占8个字节。因此,容量为20,000的列表大约为80 KB或160 KB,具体取决于运行时。 - Jim Mischel

2
当您正在绑定到列表对象并且其他代码区域引用该对象时,请使用clear方法。如果您没有引用并且未绑定,则创建新对象是适当的。

如果我想引用一个空列表,为什么清空它比只是将一个空列表分配给引用更合适? - Matthew
这真的取决于你用它做什么。如果你只是创建一个空列表作为参数传递给方法,以便在返回时引用它 - 那很好。然而,我通常会将List作为方法的返回项或out参数。 - tsells

0
小心使用Clear。它会修改实际的列表。如果你在其他地方有对同一个列表的另一个引用,可能会导致意想不到的结果。
例如:
List<int> one = new() { 1, 2, 3 };
List<int> two = one;
one.Clear(); // two is now also empty

List<int> three = new() { 1, 2, 3 };
List<int> four = three;
three = new(); // four still has values in it

因此,为了避免意外后果,我更倾向于按照通常的做法创建一个新的列表。在某些情况下可以使用清除功能,但请确保您真的想要清除它所清除的所有内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接