我正在寻找System.Collections.Generic.List<T>的开源代码。 dplyr
[1,] "dplyr"
[2,] "stats"
[3,] "graphics"
[4,] "grDevices"
[5,] "utils"
[6,] "datasets"
[7,] "methods"
[8,] "base"
方法如下:
AddRange(IEnumerable<T>)
和public void AddRange(IEnumerable<T> collection) {
Contract.Ensures(Count >= Contract.OldValue(Count));
InsertRange(_size, collection);
}
方法如下:
InsertRange(int, IEnumerable<T>)
假设我们拨打这样的电话:
public void InsertRange(int index, IEnumerable<T> collection) {
if (collection==null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
if ((uint)index > (uint)_size) {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index);
}
Contract.EndContractBlock();
ICollection<T> c = collection as ICollection<T>;
if( c != null ) {
int count = c.Count;
if (count > 0) {
EnsureCapacity(_size + count);
if (index < _size) {
Array.Copy(_items, index, _items, index + count, _size - index);
}
if (this == c) {
Array.Copy(_items, 0, _items, index, index);
Array.Copy(_items, index+count, _items, index*2, _size-index);
}
else {
T[] itemsToInsert = new T[count]; // WHY?
c.CopyTo(itemsToInsert, 0); // WHY?
itemsToInsert.CopyTo(_items, index); // WHY?
// c.CopyTo(_items, index); // WHY NOT THIS INSTEAD???
}
_size += count;
}
}
else {
using(IEnumerator<T> en = collection.GetEnumerator()) {
while(en.MoveNext()) {
Insert(index++, en.Current);
}
}
}
_version++;
}
当它在内部达到var list1 = new List<int> {0, 1, 2, 3};
var list2 = new List<int> {4, 5, 6, 7};
list1.AddRange(list2);
时,最终达到了InsertRange(int, IEnumerable<T>)
注释突出显示的else条件。
为什么要分配一个数组,将// WHY?
中的元素复制到该临时数组中,然后将元素从该临时数组中复制到list2
的末尾?为什么要额外复制?为什么不使用list1
方法将元素从list2
直接复制到list1
的末尾?
我谨谨此提出,虽然这个问题是由我们这些没有写代码开始的人来推测的,但是是一个问题的答案。编写代码的方式是有原因的,我希望有知识的人可以提供解释,即使只是出于历史目的。
答案 0 :(得分:1)
如@ OlivierJacot-Descombes的注释部分所指出的那样,有问题的多余副本已在.NET Core库(CoreFX)的当前List.cs版本中删除,并由单副本版本取代,即c.CopyTo(_items, index);
。
感谢@elgonzo和@IvanStoev提供了发人深省的评论。总结一下,这可能只是List<T>
演变的产物,它代表了@Entity
@Table(name ="cats")
public class Cat {
@Id
@Column(name="name")
private String name;
@Column(name="age")
private int age;
@Column(name="color")
private String color;
@Column(name="weight")
private int weigth;
..
}
开发时的最佳选择,但这只是一个猜测。