[英]C# - What are the best practices when creating custom lists using arrays
我有一些功课可以练习一些概念,例如泛型,委托和接口。 整个项目是使用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);
我敢肯定,有一种更好的方法来制作自定义列表,希望在那里的人对此事有深入的了解。
此实现表明,您总体上缺少封装的要点,尤其是缺少使用私有成员的要点。 由于您使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#的命名准则 ,将其从Add
的参数列表中删除,然后将Add
更改为不返回任何内容。 这将匹配IList<T>
的签名,您应该考虑实现该签名。
完成这项工作后,请考虑从currentItems
“分离” capacity
,让第一个更快地增长,而另一个随着更多项目的增加而赶上它。 这将减少重新分配的次数。
最后,请考虑切换到使用Array.Resize<T>
以避免手动复制数据。
如果查看ReferenceSource或ILSpy中List<>
的Add()
方法实现,您将看到以下内容:
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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.