問題是關於表的構造有時會調用Array.Copy比一個循環更有效嗎?
此構造/// <summary>
/// Initializes a new instance of the <see cref="T:System.Collections.Generic.List`1"/> class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied.
/// </summary>
/// <param name="collection">The collection whose elements are copied to the new list.</param><exception cref="T:System.ArgumentNullException"><paramref name="collection"/> is null.</exception>
[__DynamicallyInvokable]
public List(IEnumerable<T> collection)
{
if (collection == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
ICollection<T> collection1 = collection as ICollection<T>;
if (collection1 != null)
{
int count = collection1.Count;
if (count == 0)
{
this._items = List<T>._emptyArray;
}
else
{
this._items = new T[count];
collection1.CopyTo(this._items, 0);
this._size = count;
}
}
else
{
this._size = 0;
this._items = List<T>._emptyArray;
foreach (T obj in collection)
this.Add(obj);
}
}
我很好奇,有情況下,當收集不是的ICollection的
public List(IEnumerable<T> collection)
代碼。在這種情況下,迭代通過收集並計算元素的計數,使用List的Add方法。在每次添加列表的容量不足時,Array.Copy會發生複製。它在添加第5,第9,第17等元素(自4的倍數2)之前發生。 我很沮喪。有時候調用Array.Copy比一個循環更有效,然後複製一次?
而且我下面添加Add方法和相關方法的ensureCapacity和清單容量
public void Add(T item)
{
if (this._size == this._items.Length)
this.EnsureCapacity(this._size + 1);
this._items[this._size++] = item;
++this._version;
}
private void EnsureCapacity(int min)
{
if (this._items.Length >= min)
return;
int num = this._items.Length == 0 ? 4 : this._items.Length * 2;
if ((uint) num > 2146435071U)
num = 2146435071;
if (num < min)
num = min;
this.Capacity = num;
}
public int Capacity
{
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get
{
return this._items.Length;
}
[__DynamicallyInvokable] set
{
if (value < this._size)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_SmallCapacity);
if (value == this._items.Length)
return;
if (value > 0)
{
T[] objArray = new T[value];
if (this._size > 0)
Array.Copy((Array) this._items, 0, (Array) objArray, 0, this._size);
this._items = objArray;
}
else
this._items = List<T>._emptyArray;
}
}
該序列可以是一次性枚舉。想象一下包裝數據閱讀器的迭代器方法。 – Dennis
在這種情況下,一次枚舉在我看來是錯誤的實現IEnumerable,因爲我們無法使用包含在接口中的Reset()方法。 –
你錯了。 「Reset方法提供了COM互操作性,不一定需要實現;相反,實現者可以簡單地拋出一個NotSupportedException異常。」 – Dennis