List<T>.AddRange / InsertRange 创建临时数组
List<T>.AddRange / InsertRange creating temporary array
在查看 List.AddRange 的实现时,我发现了一些我不明白的奇怪之处。
Sourcecode, see line 727(AddRange 调用 InsertRange)
T[] itemsToInsert = new T[count];
c.CopyTo(itemsToInsert, 0);
itemsToInsert.CopyTo(_items, index);
为什么先将集合复制到 "temp-array" (itemsToInsert) 中,然后将临时数组复制到实际的 _items 数组中?
这背后有什么原因吗,或者这只是复制 ArrayList 源代码的一些遗留问题,因为那里发生了同样的事情。
我猜这是为了隐藏内部支持数组的存在。没有办法获得对该数组的引用,这是有意的。 List
class 甚至不保证有这样一个数组。 (当然,出于性能和兼容性的考虑,它将始终使用数组来实现。)
有人可以传入一个精心制作的 ICollection<T>
,它会记住传递给它的数组。现在调用者可以弄乱 List
的内部数组并开始依赖 List
内部。
将此与 MemoryStream
进行对比,后者具有访问内部缓冲区的记录方式(并用它来攻击自己):GetBuffer()
.
在查看 List.AddRange 的实现时,我发现了一些我不明白的奇怪之处。 Sourcecode, see line 727(AddRange 调用 InsertRange)
T[] itemsToInsert = new T[count];
c.CopyTo(itemsToInsert, 0);
itemsToInsert.CopyTo(_items, index);
为什么先将集合复制到 "temp-array" (itemsToInsert) 中,然后将临时数组复制到实际的 _items 数组中? 这背后有什么原因吗,或者这只是复制 ArrayList 源代码的一些遗留问题,因为那里发生了同样的事情。
我猜这是为了隐藏内部支持数组的存在。没有办法获得对该数组的引用,这是有意的。 List
class 甚至不保证有这样一个数组。 (当然,出于性能和兼容性的考虑,它将始终使用数组来实现。)
有人可以传入一个精心制作的 ICollection<T>
,它会记住传递给它的数组。现在调用者可以弄乱 List
的内部数组并开始依赖 List
内部。
将此与 MemoryStream
进行对比,后者具有访问内部缓冲区的记录方式(并用它来攻击自己):GetBuffer()
.