我有一些学校的工作来练习一些概念,如泛型,委托和接口。整个项目是使用T
数组构建自定义列表类。
该类还应实现IEnumerable
并具有IEnumerator
的结构。我这里只关注Add方法。
class MyList<T> : IEnumerable
{
private static readonly T[] arrayStarter = new T[1];
private int capacity = 1;
private int currentItems = 1;
public T[] TList { get; set; }
public MyList()
{
TList = arrayStarter;
TList[0] = default(T);
}
public T[] Add(T[] tArray, T item)
{
T[] temp = new T[++capacity];
for (int i = 0; i < tArray.Length; i++)
temp[i] = tArray[i];
temp[tArray.Length] = item;
currentItems++;
return temp;
}
}
当我创建列表的实例并且我想使用该方法添加项目时,它看起来像这样:
MyList<int> m = new MyList<int>();
m.TList = m.Add(m.TList, 5);
m.TList = m.Add(m.TList, 7);
m.TList = m.Add(m.TList, 13);
m.TList = m.Add(m.TList, 15);
我很确定有一个更好的方法来制作自定义列表我希望那里的人对此事有很好的了解。
答案 0 :(得分:4)
此实现表明您一般都缺少封装点,特别是使用私有成员。由于您将TList
数组作为列表类的成员,因此您可以完全从用户中隐藏它。您的用户应该能够写
m.Add(5);
m.Add(7);
而不是
m.TList = m.Add(m.TList, 5);
m.TList = m.Add(m.TList, 7);
并且根本不担心m.TList
的存在。
幸运的是,您可以非常轻松地执行此操作:将TList
设为私有字段,将其重命名为以小写字母开头的内容,以跟随C#'s naming guidelines,将其从{{1}列表中删除}&#39; s参数,并将Add
更改为不返回任何内容。这符合IList<T>
的签名,您应该考虑实施。
一旦你完成了这项工作,请考虑&#34;离婚&#34;来自Add
的{{1}},让第一个增长得更快,另一个追加更多项目。这将减少重新分配的数量。
最后一点,请考虑切换到使用Array.Resize<T>
以避免手动复制数据。
答案 1 :(得分:0)
如果您查看ReferenceSource中的List<>
Add()
方法实施或ILSpy,您会看到:
private int _size;
private T[] _items;
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)
{
int num = (this._items.Length != 0) ? (this._items.Length * 2) : 4;
if (num > 2146435071)
{
num = 2146435071;
}
if (num < min)
{
num = min;
}
this.Capacity = num;
}
}