首先看看接口
public interface ICustomArrayList<T>
{
/// <summary>
/// 集合实际元素大小
/// </summary>
int Count { get; }
/// <summary>
/// 容量大小
/// </summary>
int Capacity { get; set; }
/// <summary>
/// 添加元素
/// </summary>
/// <param name="t"></param>
void Add(T t);
/// <summary>
/// 移除元素
/// </summary>
/// <param name="t"></param>
void Remove(T t);
/// <summary>
/// 索引器
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public T this[int index] { get; set; }
}
实现类
public class CustomArrayList<T> : ICustomArrayList<T>
{
/// <summary>
/// 存储元素
/// </summary>
private T[] _arraySrc;
/// <summary>
/// 集合实际元素大小
/// </summary>
private int _size;
/// <summary>
/// 默认初始容量
/// </summary>
private const int DEFAULTCAPACITY = 4;
/// <summary>
/// 最大容量
/// </summary>
private const int MAXCAPACITY = 0x7FEFFFFF;
/// <summary>
/// T类型的字节大小
/// </summary>
private readonly int TSizeOf;
public int Count => this._size;
private IComparer<T> _comparer = Comparer<T>.Default;
public CustomArrayList() : this(0)
{
}
public CustomArrayList(int capacity)
{
if (capacity < 0)
throw new Exception("不能小于零");
TSizeOf = typeof(T).IsPrimitive ? Marshal.SizeOf<T>() : -1;
this._arraySrc = new T[capacity];
}
public void Add(T t)
{
if (this._size == this._arraySrc.Length)
EnsureCapacity(this._size + 1);// 确保容器在合理范围
this._arraySrc[this._size++] = t;
}
private void EnsureCapacity(int min)
{
if (this._arraySrc.Length < min)
{
int num = this._arraySrc.Length == 0 ? DEFAULTCAPACITY : this._arraySrc.Length << 1;
if (num > MAXCAPACITY)
num = MAXCAPACITY;
if (num < min)
num = min;
this.Capacity = num;
}
}
public int Capacity
{
get => this._arraySrc.Length;
set
{
if (value < this._size)
throw new ArgumentOutOfRangeException("ArgumentOutOfRange_SmallCapacity");
if (value != this._arraySrc.Length)
{
if (value > 0)
{
// 当设容量更改时,声明一个更大的新数组,达到扩容的效果
T[] tempArray = new T[value];
if (this._size > 0)
{
if (TSizeOf == -1)
{
// Array.Copy(this._arraySrc, 0, tempArray, 0, this._size);
Array.ConstrainedCopy(this._arraySrc, 0, tempArray, 0, this._size);
}
else
{
int size = this._size * TSizeOf;
Buffer.BlockCopy(this._arraySrc, 0, tempArray, 0, size);
}
}
this._arraySrc = tempArray;
return;
}
this._arraySrc = new T[DEFAULTCAPACITY];
}
}
}
public T this[int index]
{
get
{
if (index >= this._size || index < 0)
throw new ArgumentOutOfRangeException("ArgumentOutOfRange");
return this._arraySrc[index];
}
set
{
if (index >= this._size || index < 0)
throw new ArgumentOutOfRangeException("ArgumentOutOfRange");
this._arraySrc[index] = value;
}
}
public override string ToString()
{
StringBuilder builder = new StringBuilder(this._size);
for (int i = 0; i < this._size; i++)
{
builder.Append($"{this._arraySrc[i]?.ToString()},");
}
return builder.Remove(builder.Length - 1, 1).ToString();
}
public void Remove(T t)
{
T temp;
for (int i = 0; i < Count; i++)
{
temp = this._arraySrc[i];
if (_comparer.Compare(t, temp) == 0)
{
for (int j = i; j < Count - 1; j++)
{
this._arraySrc[j] = this._arraySrc[j + 1];
}
this._size--;
break;
}
}
}
}