I've got some school work to practice some concepts like generics, delegates, and interfaces. The whole project is to build a custom list class using an array of T
. the class should also implement IEnumerable
and have a struct which is an IEnumerator
. I'm only focusing on the Add method here.
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;
}
}
When I'm creating an instance of my list and I want to add an item using the method it looks like this:
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);
I'm pretty sure there's a better way to make a custom list I hope someone out there has a good insight on the matter.
This implementation demonstrates that you are missing the point of encapsulation in general, and of using private members in particular. Since you made TList
array a member of your list class, you have an ability to hide it from your users completely. Your users should be able to write
m.Add(5);
m.Add(7);
instead of
m.TList = m.Add(m.TList, 5);
m.TList = m.Add(m.TList, 7);
and not worry about m.TList
's presence at all.
Fortunately, you can do it very easily: make TList
a private field, rename it to something that starts in lower case letter to follow C#'s naming guidelines , remove it from the list of Add
's parameters, and change Add
to not return anything. This would match IList<T>
's signature, which you should consider implementing.
Once you've made this work, consider "divorcing" capacity
from currentItems
, letting the first one grow faster, and the other one catching up to it as more items are added. This would reduce the number of re-allocations.
As a final point, consider switching to using Array.Resize<T>
to avoid manual copying of data.
If you take a look at List<>
's Add()
method implementation in ReferenceSource or with ILSpy, you'll see this:
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;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.