using System; using System.Collections; using System.Collections.Generic; namespace AX.AudioSystem { /// /// 构造一个暴露内部数组的 List。 /// internal class BetterList { private const int DefaultCapacity = 4; private const int MaxArrayLength = 0x7fefffff; private static readonly T[] emptyArray = new T[0]; private T[] items; private int size; public BetterList() { items = emptyArray; } public BetterList(int capacity) { if (capacity < 0) throw new ArgumentOutOfRangeException("capacity"); if (capacity == 0) items = emptyArray; else items = new T[capacity]; } public int Capacity { get { return items.Length; } set { if (value < size) throw new ArgumentOutOfRangeException("capacity"); if (value != items.Length) { if (value > 0) { T[] newItems = new T[value]; if (size > 0) Array.Copy(items, 0, newItems, 0, size); items = newItems; } else items = emptyArray; } } } public int Count { get { return size; } } public T this[int index] { get { if ((uint)index >= (uint)size) throw new ArgumentOutOfRangeException(); return items[index]; } set { if ((uint)index >= (uint)size) throw new ArgumentOutOfRangeException(); items[index] = value; } } public void Add(T item) { if (size == items.Length) EnsureCapacity(size + 1); items[size++] = item; } public void AddRange(IEnumerable enumerable) { if (enumerable == null) throw new ArgumentNullException("enumerable"); ICollection collection = enumerable as ICollection; if (collection != null) { int count = collection.Count; if (count > 0) { EnsureCapacity(size + count); collection.CopyTo(items, size); size += count; } } else { foreach (var item in enumerable) Add(item); } } public void AddRange(T[] data, int offset, int count) { if (data == null) throw new ArgumentNullException("data"); if (offset < 0) throw new ArgumentOutOfRangeException("offset"); if(count < 0) throw new ArgumentOutOfRangeException("count"); if (data.Length - offset < count) throw new ArgumentOutOfRangeException("data, offset, count"); if(count > 0) { EnsureCapacity(size + count); Array.Copy(data, offset, items, size, count); size += count; } } public void AddRange(T[] data) { AddRange(data, 0, data.Length); } public void Clear() { if (size > 0) { Array.Clear(items, 0, size); size = 0; } } public bool Contains(T item) { if ((Object)item == null) { for (int i = 0; i < size; i++) if ((Object)items[i] == null) return true; return false; } else { EqualityComparer comparer = EqualityComparer.Default; for (int i = 0; i < size; i++) { if (comparer.Equals(items[i], item)) return true; } return false; } } public void CopyTo(T[] array) { CopyTo(array, 0); } public void CopyTo(int index, T[] array, int arrayIndex, int count) { if (size - index < count) throw new ArgumentException(); Array.Copy(items, index, array, arrayIndex, count); } public void CopyTo(T[] array, int arrayIndex) { Array.Copy(items, 0, array, arrayIndex, size); } private void EnsureCapacity(int min) { if (items.Length < min) { int newCapacity = items.Length == 0 ? DefaultCapacity : items.Length * 2; if ((uint)newCapacity > MaxArrayLength) newCapacity = MaxArrayLength; if (newCapacity < min) newCapacity = min; Capacity = newCapacity; } } public int IndexOf(T item) { return Array.IndexOf(items, item, 0, size); } public int IndexOf(T item, int index) { if (index > size) throw new ArgumentOutOfRangeException("index"); return Array.IndexOf(items, item, index, size - index); } public int IndexOf(T item, int index, int count) { if (index > size) throw new ArgumentOutOfRangeException("index"); if (count < 0 || index > size - count) throw new ArgumentOutOfRangeException("count"); return Array.IndexOf(items, item, index, count); } public bool Remove(T item) { int index = IndexOf(item); if (index >= 0) { RemoveAt(index); return true; } return false; } public void RemoveAt(int index) { if ((uint)index >= (uint)size) throw new ArgumentOutOfRangeException(); size--; if (index < size) { Array.Copy(items, index + 1, items, index, size - index); } items[size] = default(T); } public void RemoveRange(int index, int count) { if (index < 0) throw new ArgumentOutOfRangeException("index"); if (count < 0) throw new ArgumentOutOfRangeException("count"); if (size - index < count) throw new ArgumentOutOfRangeException(); if (count > 0) { size -= count; if (index < size) Array.Copy(items, index + count, items, index, size - index); Array.Clear(items, size, count); } } public T[] ToArray() { var array = new T[size]; CopyTo(array); return array; } /// /// 获得原始的数组。特别注意:不要对此数组进行操作。 /// public T[] GetBuffer() { return items; } public void TrimExcess() { int threshold = (int)(((double)items.Length) * 0.9); if (size < threshold) Capacity = size; } } }