Я смотрю на открытый исходный код для System.Collections.Generic.List .Метод 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
, используя метод ICollection<T>.CopyTo()
?
РЕДАКТИРОВАТЬ
Я бы с уважением заявил, что пока вопросПри условии спекуляции со стороны тех из нас, кто не написал код для начала, тем не менее, является ответом на вопрос.Есть причина, по которой код был написан таким, каким он был, и я надеялся, что кто-то, обладающий такими знаниями, сможет дать объяснение, даже если только для исторических целей.