创建列表(而不是其中的对象)的独立副本的最快方法是什么

本文关键字:副本 独立 是什么 方法 对象 创建 列表 | 更新日期: 2023-09-27 18:31:48

假设我有一个ListA。我想制作一个重复的列表B,所以当我使用ListB.Remove(SomeItem);它不会影响列表A。

列表项应引用相同的对象。

由于这是在循环中使用的,因此使用资源需求最少的方法非常重要。但我不知道如何以最有效的方式做到这一点。

创建列表(而不是其中的对象)的独立副本的最快方法是什么

你想要一个浅层克隆,你可以简单地使用这个List<T>构造函数来完成:

var shallowClone = new List(originalList);

请注意,此构造函数的实现检查originalList是否支持 Count 属性,如果支持,则使用它来预先调整列表大小以避免不必要的内存分配。这使得它非常理想:

_items = new T[count];
c.CopyTo(_items, 0);
_size = count;

但是,我已经查看了Enumerable<T>.ToList()的实现,它所做的只是调用上面的List<T>构造函数。

所以这段代码做几乎完全相同的事情(并且将以相同的速度运行):

var shallowClone = originalList.ToList();

您可以简单地调用ListB.ToList(),这将从共享相同元素ListB创建一个新列表。对ListB的元素SET的更改不会反映在A中,但是如果您更改任何元素,它都会反映在两个列表中。

在您的情况下,您可以使用列表泛型方法。在类中添加此方法。

public static List<T> Clone<T>(this List<T> myList)
{
    var newList = new List<T>(myList.Capacity);
    newList.AddRange(myList);
    return newList;
}
有趣的是

,似乎没有人在寻找一种专门的List<T>方法(根据定义应该具有最佳实现),并且有一种称为GetRange的方法,根据文档

创建源 List 中一系列元素的浅表副本。

因此,创建整个源列表的浅拷贝将是这样的

var shallowClone = originalList.GetRange(0, originalList.Count);

附言当然性能差异最简洁

var shallowClone = originalList.ToList();

而且不是那么简洁

var shallowClone = new List<MyLongListItemType>(originalList);

可以忽略不计。

所以我个人更喜欢ToList版本,同时会记住不要在我的代码中调用ToList不需要(我在很多地方都见过),因为该方法的复制行为。